Django: лучший способ реализовать поле "статус" в модулях
У меня есть поле в моем модуле, которое используется для хранения статуса объекта.
До сих пор я использовал:
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 enum {}. Или, может быть, существует совершенно другой способ решить эту проблему?
Спасибо
Ответы
Ответ 1
Возможно, этот вопрос поможет вам: Установить Django IntegerField по выбору =... name.
Я цитирую принятый ответ (с настройками;)):
Поместите это в свой класс (STATUS_CHOICES
будет списком, который передается в поле choices
в поле):
PENDING = 0
DONE = 1
STATUS_CHOICES = (
(PENDING, 'Pending'),
(DONE, 'Done'),
)
Тогда вы можете сделать order.status = Order.DONE
.
Примечание, что вы не должны реализовать собственный метод для получения значения (читаемого), Django предоставляет метод get_status_display
.
Ответ 2
что я обычно делаю для этой ситуации:
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']
Ответ 3
Это очень поздний ответ, однако для полноты я должен упомянуть, что django-model-utils уже содержит StatusField и даже лучше a StatusModel. Я использую его везде, где мне нужно иметь статус.
Ответ 4
вы можете попробовать пакет enum:
http://pypi.python.org/pypi/enum/
Ответ 5
Вам не нужен ваш метод 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')
Ответ 6
Возможно, наденьте метод на модель, например:
def status_code(self, text):
return [n for (n, t) in self.ORDER_STATUS if t == text][0]
Затем выполните следующие действия:
order.status = order.status_code('Error')
Ответ 7
не выполняйте все эти вещи. Просто внесите изменения в views.py следующим образом
context['value'] = Model_name.objects.order_by('-choice')
где
choice = ('pending','solved','closed')