简体   繁体   中英

Difference between queryset attribute and get_queryset() method in django?

I am learning class based views in Django. I was reading the Django documentation and read about queryset attribute and the get_queryset() method. When googled them I came across this answer .

I tried to replicate the result using my code:

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        return Question.objects.order_by('-pub_date')[:2]

class IndexView2(generic.ListView):
    template_name = 'polls/index2.html'
    context_object_name = 'latest_question_list2'
    queryset = Question.objects.all()

In answer it is mentioned that 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.

But I was able to insert questions in database and they were available in the page index2.html without restarting, I was able to change the database and changes were reflected on the page index2.html after refreshing the page.

I further googled and found this link . In the DRF website, it is mentioned that queryset will get evaluated once, and those results will be cached for all subsequent requests.

Can you point where I am going wrong? What link I am missing?

A QuerySet is evaluated once, but the default implementation of get_queryset , will use queryset.all() , thus each time constructing a new queryset that will force reevaluation.

Indeed, the implementation of the .get_queryset(…) method [GitHub] works with:

 def get_queryset(self): if self.queryset is not None: queryset = self.queryset if isinstance(queryset, QuerySet): queryset =  elif self.model is not None: queryset = self.model._default_manager.all() else: raise ImproperlyConfigured( "%(cls)s is missing a QuerySet. Define " "%(cls)s.model, %(cls)s.queryset, or override " "%(cls)s.get_queryset()." % { 'cls': self.__class__.__name__ } ) ordering = self.get_ordering() if ordering: if isinstance(ordering, str): ordering = (ordering,) queryset = queryset.order_by(*ordering) return queryset

THis thus means that we each time make a new "copy" of the QuerySet that will be evaluated. In case the queryset is not specified, it will look for the model attribute, and work with the _default_manager for that model.

If you specified an ordering attribute, than that means it will also order the queryset.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM