[Fixed]-Django: using values() and get_FOO_display()?


In general, it’ll probably be better and easier to use a Manager-based query that returns model objects. It sounds like the issue with your original approach is not that you were iterating over your queryset (as @ahmoo says, this isn’t a performance issue), but that within your iteration loop you were getting additional related objects, requiring one or more additional queries for each record.

There are several ways to improve performance with queries that still return model instances:

  • It sounds like the most relevant is select_related(), which will effectively do a table join on the initial query to include data for all objects related by foreign keys.

  • If that’s insufficient, you can also add data to your model instances with extra(), which allows you to stick subqueries into your SQL.

  • And if all that fails, you can perform raw SQL queries using the .raw() method on a Manager instance, which will still return model instances.

Basically, if you can do it in SQL in a way that gives you one row per instance, there’s a way to do it in Django and get model instances back.

To answer your original question, though, you can get the display name through the Field class – it’s just ugly:

def get_field_display(klass, field, value):
    f = klass._meta.get_field(field)
    return dict(f.flatchoices).get(value, value)

# usage
get_field_display(User, 'name', 'JSmith001')


iterating over querysets is generally a bad idea, because SQL is executed for each item

That’s not true. Below is taken from the official docs:

A QuerySet is iterable, and it executes its database query the first time you iterate over it

I think the problem has to do with the definition of the users from your code. What did you assign to it?

Leave a comment