7👍
✅
I think the easiest way would be to use only()
instead of values()
. Like values
, only
retrieves a subset of the database columns. The difference is that it creates model instance objects, which means that you can use get_X_display()
as usual.
instances = MyModel.objects.filter(a='1').only('id', 'a', 'choicefield')
instances[0].get_choicefield_display() # will work fine
Of course, you should check out the caveats in the documentation on only()
and defer()
, but for the purposes you’ve described I don’t see a problem.
If you want to use values()
there are many ways to solve this problem. One approach is to define the mapping explicitly in your model:
from collections import OrderedDict
class MyModel(models.Model):
CHOICES_DICT = OrderedDict((
(1, 'Choice 1'),
(2, 'Choice 2'),
))
choicefield = models.IntegerField(choices=CHOICES_DICT.items())
...
Now you can explicitly look up up the string value in your view:
values = MyModel.objects.filter(a='1').values('id','a','choicefield')
name = MyModel.CHOICES_DICT[values[0]['choicefield']]
You could also create a custom template filter to do the same thing at the template level.
Source:stackexchange.com