2015-02-03 5 views
1

У меня есть модель, в которой одно поле часто является пустой строкой. Есть ли способ вернуть (например,) строку «default» вместо этой пустой строки для запросов на эту модель?вернуть значение по умолчанию для пустого поля в модели django

class MyModel(models.Model): 
    ... 
    afield = models.CharField(...) # many rows set afield to '' 

Когда я выполнить запрос

o = MyModel.objects.all() 
vars(o[0]) 
{... 
'afield': '' # afield is empty 
...} 

Я предпочел бы видеть

vars(o[0]) 
{... 
'afield': 'default' 
...} 

Есть ли способ сделать это? Есть ли лучший способ реализовать это, чем внутри модели?

Примечания:

  • Я не хочу, чтобы сохранить строку 'по умолчанию'
  • this answer изменяет базу данных, я хочу, чтобы избежать этого
+0

почему бы не сохранить значение? Если вы действительно этого не хотите, подумайте о создании функции доступа или фильтра шаблонов. Ответ все зависит от того, как вы используете данные; так что, возможно, пример того, как вы будете использовать 'MyModel.objects.all()' после извлечения его, поможет. –

+0

Мои пользователи ожидают увидеть «по умолчанию», когда веб-страница заполняется этим полем. –

ответ

1

Это, вероятно, много, много , много лучше обрабатывать это во взглядах как часть вашей логики, но вы можете использовать свойства и сеттеры для этого:

class MyModel(models.Model): 
    _afield = models.CharField(...) 
    @property 
    def afield(self): 
     if self._afield: 
      return self._afield 
     else: 
      return "default" 

    @afield.setter 
    def afield_setter(self,value): 
     self._afield = value 
+0

Зачем это делать во взглядах? Если я возвращаю ответ REST, я должен пройти каждый элемент в наборе запросов и изменить это поле в своем сериализаторе. «Жирные модели и тонкие взгляды» мне кажутся хорошей практикой. –

+0

Ответ REST по-прежнему является «представлением» на модели, а не «бизнес-логикой». Если значение по умолчанию было «бизнес-логикой», вы фактически его сохранили. Я думаю, что есть вещи, о которых вы не говорите нам о «поле», которые помогут вам получить лучший ответ. –

+1

Я храню ссылки на Mercurial changesets. Когда набор изменений не находится на ветке, он находится в «умолчанию». При просмотре набора изменений через 'hg log' поле ветвей является пустой строкой для наборов изменений не на ветке. –

3

Вы можете переопределить __getattribute__() метод:

class MyModel(models.Model): 
    .... 
    def __getattribute__(self, name): 
     attr = models.Model.__getattribute__(self, name) 
     if name == 'afield' and not attr: 
      return 'default' 
     return attr 

Вот является использование:

>>> obj = MyModel() 
>>> obj.afield 
'default' 
>>> getattr(obj, 'afield') 
'default' 
>>> obj.afield = 'test' 
>>> obj.afield 
'test' 
>>> getattr(obj, 'afield') 
'test' 
>>> obj.afield = '' 
>>> obj.afield 
'default' 
>>> # other properties work as usual 
>>> obj.some_var = 123 
>>> obj.some_var 
123 
+0

Что делать, если есть другие свойства, которые не определены в 'models.Model'? –

+0

@LegoStormtroopr они будут работать как обычно. Вы можете установить/получить любой атрибут этого класса. – catavaran

+0

__getattribute __() в конечном итоге разрешено для извлечения из базы данных? Это звучит здорово. Почему это проголосовало? –

Смежные вопросы