Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use get_queryset() method or set queryset variable?

These two pieces of code are identical at the first blush:

class IndexView(generic.ListView):     template_name = 'polls/index.html'     context_object_name = 'latest_poll_list'     queryset = Poll.active.order_by('-pub_date')[:5] 

and

class IndexView(generic.ListView):     template_name = 'polls/index.html'     context_object_name = 'latest_poll_list'      def get_queryset(self):         return Poll.active.order_by('-pub_date')[:5] 

Is there any difference between them? And if it is:

What approach is better? Or when setting queryset variable is better than override the get_queryset method? And vice versa.

like image 891
9Algorithm Avatar asked Oct 31 '13 13:10

9Algorithm


People also ask

What is super () Get_queryset ()?

super() is used to obtain the implementation of get_queryset that is the next in the method resolution order (MRO). If classes would have only one baseclass, you could think of this as the parent class, but in Python multiple inheritance is allowed, and thus the rules of the MRO are more compilcated.

What is Get_queryset in Django?

get_queryset() Used by ListView s - it determines the list of objects that you want to display. By default, it will just give you all for the model you specify. By overriding this method you can extend or completely replace this logic. Django documentation on the subject.

What is get Queryset?

get_queryset: get_queryset() Returns the queryset that will be used to retrieve the object that this view will display. By default, get_queryset() returns the value of the queryset attribute if it is set, otherwise it constructs a QuerySet by calling the all() method on the model attribute's default manager.


2 Answers

In your example, overriding queryset and get_queryset have the same effect. I would slightly favour setting queryset because it's less verbose.

When you set queryset, the queryset is created only once, when you start your server. On the other hand, the get_queryset method is called for every request.

That means that get_queryset is useful if you want to adjust the query dynamically. For example, you could return objects that belong to the current user:

class IndexView(generic.ListView):     def get_queryset(self):         """Returns Polls that belong to the current user"""         return Poll.active.filter(user=self.request.user).order_by('-pub_date')[:5] 

Another example where get_queryset is useful is when you want to filter based on a callable, for example, return today's polls:

class IndexView(generic.ListView):     def get_queryset(self):         """Returns Polls that were created today"""         return Poll.active.filter(pub_date=date.today()) 

If you tried to do the same thing by setting queryset, then date.today() would only be called once, when the view was loaded, and the view would display incorrect results after a while.

class IndexView(generic.ListView):     # don't do this!     queryset = Poll.active.filter(pub_date=date.today()) 
like image 72
Alasdair Avatar answered Sep 20 '22 12:09

Alasdair


Other answers have missed an important implication of the fact that the queryset attribute is evaluated when the process starts. Because you aren't just creating a queryset, you're actually slicing it, the query will be evaluated at that point. That means that you will only ever get the top 5 polls at that moment, and they won't refresh even if you create another one, until the process is restarted.

This is exactly when you should be using get_queryset().

like image 29
Daniel Roseman Avatar answered Sep 19 '22 12:09

Daniel Roseman