django query with values(), not fetching get_absolute_url

Hi, I tried the following query and I got the get_absolute_url and a human readable version of a choice field in my django template (get_FOO_diplay) working correctly ,

def get_queryset(self):
        return Task.objects.filter(status='c') \ 
            .select_related('created_by', 'boat', 'assigned_to').all()

However when use the same query with values(), neither my get_absolute_url or get_FOO_diplay seems to work correctly, following is my query:

def get_queryset(self):
        return Task.objects.filter(status='c') \
            .select_related('created_by', 'boat', 'assigned_to') \
                .values('created_by__username','boat__name','name', 'status', 'created_date')

Note: the status is the choice field,
can anyone point out what I am doing wrong here.


.values will return a dictionary, not the model instance. So you won’t be able to use functions from it.

To amplify @fabtjar 's answer a little, and assuming you’re using CBVs, the get_queryset function is supposed to return a queryset (values doesn’t).
Review the docs at QuerySet API reference | Django documentation | Django to see what functions return querysets and which don’t. You shouldn’t be using any function on your query that doesn’t return a queryset in that method.

I cannot acces any methods inside my model class, if I use value() function right. think i’ll need to experiment with other querset apis. Thanks

Side note: Not just the values function. You can’t chain any function that doesn’t return a queryset as listed in the referenced docs.

It would perhaps be more instructive to understand why you think you need (or want) to use values at that location.

I’m thinking of reducing my queries. Right now my queryset is getting more information than I need, since few related table are included.

For the moment, only the values() function is querying the desired result. However I am reading through the docs to figure it out. Thanks

Unless you can demonstrate an actual “problem” with this, supported by metrics, I suggest you not worry about it.

In the general case:

  • You’ve probably spent more time thinking about this issue than you will ever save over the life of your project.
  • By definition, get_queryset is supposed to return a queryset, not a list.
  • Keeping it as a queryset makes other changes easier going forward. Should you ever change your view, you won’t need to go back and change your get_queryset method.
1 Like

Thanks very much, will take that to consideration.