Django: Best way to implement "status" field in modules
Question:
I have a field in my module that is used to hold the status of the object.
So far I have used:
ORDER_STATUS = ((0, 'Started'), (1, 'Done'), (2, 'Error'))
status = models.SmallIntegerField(choices=ORDER_STATUS)
Its easy to convert one way:
def status_str(self): return ORDER_STATUS[self.status][1]
The problem is when updating. I find myself having code like this:
order.status = 2 # Error Status
Which is quite awful and gets really hard to synchronize. I guess a solution would be something similar to C’s enum{}. Or perhaps there is a whole different way to tackle this problem ?
Thanks
Answers:
you can try enum package:
http://pypi.python.org/pypi/enum/
Maybe this question helps you: Set Django IntegerField by choices=… name.
I quote from the accepted answer (with adjustments ;)):
Put this into your class (STATUS_CHOICES
will be the list that is handed to the choices
option of the field):
PENDING = 0
DONE = 1
STATUS_CHOICES = (
(PENDING, 'Pending'),
(DONE, 'Done'),
)
Then you can do order.status = Order.DONE
.
Note that you don’t have to implement an own method to retrieve the (readable) value, Django provides the method get_status_display
itself.
You don’t need your status_str
method – Django automatically provides a get_status_display()
which does exactly the same thing.
To reverse, you could use this:
def set_order_status(self, val):
status_dict = dict(ORDER_STATUS)
self.status = status_dict[val][0]
Now you can do:
order.set_order_status('Done')
what I usually do for this situation is:
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)
Now you can do:
from static import ORDER_STATUS_DICT
order.status = ORDER_STATUS_DICT['Error']
Maybe stick a method on the model, like:
def status_code(self, text):
return [n for (n, t) in self.ORDER_STATUS if t == text][0]
Then you’d do:
order.status = order.status_code('Error')
This is a very late answer, however for completeness I should mention that django-model-utils already contains a StatusField and even better a StatusModel. I am using it everywhere I need to have a status.
don’t do all those things.just make change in views.py as follows
context['value'] = Model_name.objects.order_by('-choice')
where
choice = ('pending','solved','closed')
I have a field in my module that is used to hold the status of the object.
So far I have used:
ORDER_STATUS = ((0, 'Started'), (1, 'Done'), (2, 'Error'))
status = models.SmallIntegerField(choices=ORDER_STATUS)
Its easy to convert one way:
def status_str(self): return ORDER_STATUS[self.status][1]
The problem is when updating. I find myself having code like this:
order.status = 2 # Error Status
Which is quite awful and gets really hard to synchronize. I guess a solution would be something similar to C’s enum{}. Or perhaps there is a whole different way to tackle this problem ?
Thanks
you can try enum package:
http://pypi.python.org/pypi/enum/
Maybe this question helps you: Set Django IntegerField by choices=… name.
I quote from the accepted answer (with adjustments ;)):
Put this into your class (STATUS_CHOICES
will be the list that is handed to the choices
option of the field):
PENDING = 0
DONE = 1
STATUS_CHOICES = (
(PENDING, 'Pending'),
(DONE, 'Done'),
)
Then you can do order.status = Order.DONE
.
Note that you don’t have to implement an own method to retrieve the (readable) value, Django provides the method get_status_display
itself.
You don’t need your status_str
method – Django automatically provides a get_status_display()
which does exactly the same thing.
To reverse, you could use this:
def set_order_status(self, val):
status_dict = dict(ORDER_STATUS)
self.status = status_dict[val][0]
Now you can do:
order.set_order_status('Done')
what I usually do for this situation is:
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)
Now you can do:
from static import ORDER_STATUS_DICT
order.status = ORDER_STATUS_DICT['Error']
Maybe stick a method on the model, like:
def status_code(self, text):
return [n for (n, t) in self.ORDER_STATUS if t == text][0]
Then you’d do:
order.status = order.status_code('Error')
This is a very late answer, however for completeness I should mention that django-model-utils already contains a StatusField and even better a StatusModel. I am using it everywhere I need to have a status.
don’t do all those things.just make change in views.py as follows
context['value'] = Model_name.objects.order_by('-choice')
where
choice = ('pending','solved','closed')