Django: лучший способ реализовать поле «status» в модулях - PullRequest
37 голосов
/ 26 января 2010

В моём модуле есть поле, которое используется для хранения статуса объекта.До сих пор я использовал:

ORDER_STATUS = ((0, 'Started'), (1, 'Done'), (2, 'Error'))
status = models.SmallIntegerField(choices=ORDER_STATUS)

Его легко конвертировать одним способом:

def status_str(self): return ORDER_STATUS[self.status][1]

Проблема при обновлении.Я обнаружил, что у меня есть такой код:

order.status = 2 # Error Status

, который довольно ужасен и его очень сложно синхронизировать.Я думаю, что решение будет что-то похожее на перечисление C {}.Или, возможно, существует совершенно другой способ решения этой проблемы?

Спасибо

Ответы [ 7 ]

38 голосов
/ 26 января 2010

Может быть, этот вопрос поможет вам: Установите Django IntegerField с помощью выбора =… name .
Цитирую из принятого ответа (с корректировками;)):
Поместите это в свой класс (STATUS_CHOICES будет списком, который передается опции choices поля):

PENDING = 0
DONE = 1
STATUS_CHOICES = (
    (PENDING, 'Pending'),
    (DONE, 'Done'),
)

Тогда вы можете сделать order.status = Order.DONE.


Обратите внимание , что вы не должны реализовывать собственный метод для извлечения (читаемого) значения, Django предоставляет сам метод get_status_display .

8 голосов
/ 26 января 2010

что я обычно делаю в этой ситуации:

models.py

from static import ORDER_STATUS    
status = models.PositiveSmallIntegerField(choices=ORDER_STATUS)

static.py

ORDER_STATUS = ((0, 'Started'), (1, 'Done'), (2, 'Error'))
ORDER_STATUS_DICT = dict((v, k) for k, v in ORDER_STATUS)

Теперь вы можете сделать:

from static import ORDER_STATUS_DICT
order.status = ORDER_STATUS_DICT['Error']
5 голосов
/ 24 сентября 2014

Это очень поздний ответ, однако для полноты я должен упомянуть, что django-model-utils уже содержит StatusField и даже лучше StatusModel . Я использую его везде, где мне нужен статус.

2 голосов
/ 26 января 2010

Вам не нужен ваш метод status_str - Django автоматически предоставляет get_status_display(), который делает то же самое.

Чтобы повернуть вспять, вы можете использовать это:

def set_order_status(self, val):
    status_dict = dict(ORDER_STATUS)
    self.status = status_dict[val][0]

Теперь вы можете сделать:

order.set_order_status('Done')
2 голосов
/ 26 января 2010

Вы можете попробовать пакет enum: http://pypi.python.org/pypi/enum/

0 голосов
/ 09 июля 2016

не делайте всех этих вещей. Просто внесите изменения в views.py следующим образом

  context['value'] = Model_name.objects.order_by('-choice')

где

   choice = ('pending','solved','closed')
0 голосов
/ 26 января 2010

Может быть, применить метод на модели, например:

def status_code(self, text):
    return [n for (n, t) in self.ORDER_STATUS if t == text][0]

Тогда вы сделаете:

order.status = order.status_code('Error')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...