S. Hadi
S. Hadi

Reputation: 65

Django values_list with choices field

The values_list in filtering object, really helps me a lot in providing solution within django view.

My code is like the following and this one works:

values_list_ac = realdata.objects.filter(product = '1').values_list('company', 'brand', 'created_by__username')

while username is the field exists in different model outside the current realdata model.

But the following code doesn't work, for I want to show the value of ac_type, which based on choices field within the same realdata model. (I try to solve it by using the same solution which work in template):

values_list_ac = realdata.objects.filter(product = '1').values_list('company', 'brand', 'created_by__username', 'get_ac_type_display')

Is there a solution other than get_ac_type_display to show the field value?

I really appreciate for some shed of light.

Edit: This my model:

    class realdata(models.Model):
        company = models.CharField(max_length=60, verbose_name="Company")
        brand = models.CharField(_('brand'), max_length=60) 
        model = models.CharField(max_length=60)
        type_choices = (
            (u'1', u'Inverter'),
            (u'2', u'Non-Inverter'),
        )
        ac_type = models.CharField(max_length=60, verbose_name="Type", choices=type_choices)
        created_by = models.ForeignKey(User)

Many Thanks!

Upvotes: 5

Views: 6769

Answers (1)

jro
jro

Reputation: 9474

The values_list function will just get the values stored in the database. When defining choices on your model's field, it will store the first value of the tuple, hence this will be what you'll retrieve.

This means that you have to look at the choices tuple to determine the display value for the item. The purpose of the get_foo_display is to give you this human-readable value, but it needs a model instance to work on.

So, a solution to resolving this yourself would be to inspect the choices, and convert the data accordingly. The following should be able to do this:

result = []
for p in realdata.objects.filter(product='1').values_list(
                          'company', 'brand', 'created_by__username', 'ac_type'):
    choice = {k: v for k, v in realdata.type_choices}[p[-1]]
    result.append(list(p[:-1]) + [choice])

The result variable will contain the converted list. The new variable is needed because the values_list function will return a list of tuples; the latter being unmutable. Also, take care to have the value you'll want to resolve as the last item in your values_list call, or adapt the above to match.

Upvotes: 2

Related Questions