Reputation: 375
Could someone explain why overriding get_queryset
and referencing the queryset via self
completely caches the page? I need to wait 5 minutes or more before updates made to the database display.
I'm trying to save a temporary value to the each object and pass it to the template.
I've got everything working fine and dandy in example 3 but don't really understand what I did to make it work, so any insight would be great!
class AppointmentListView(ListView):
qs = Appointment.objects.prefetch_related('client', 'patients')
def get_queryset(self):
for r in self.qs:
r.css = 'abc' #<-passes temp value to template ok
return self.qs
If I don't include a method and just have the queryset called automatically, there is no caching and database updates display immediately, but my temp data does not reach template. class AppointmentListView(ListView):
queryset = Appointment.objects.prefetch_related('client','patients')
for r in queryset:
r.css = 'abc' #<- NOT passed to template
Finally if I put everything in the method, it all works fine - temp data reaches the template and there's no caching.
class AppointmentListView(ListView):
def get_queryset(self):
qs = Appointment.objects.prefetch_related('client','patients')
for r in qs:
r.css = 'abc' #<-passes to template ok
return qs
Upvotes: 1
Views: 553
Reputation: 13058
The behavior you're seeing is how Python evaluates your code. Below is a simplified example that explains what you're seeing.
import random
class Example1(object):
roll = random.randint(1, 6) # this is evaluated immediately!
def get_roll(self):
return self.roll
ex1 = Example1()
# the call below always returns the same number!
# (until Python re-interprets the class)
ex1.get_roll()
If you type the code above into a python interpreter, you'll notice that ex1.get_roll()
always returns the same number!
Example1.roll
is known as a class or static variable. These are evaluated only once when the class is defined.
class Example2(object):
def get_number(self):
roll = random.randint(1,6)
return roll
In Example2
, a new random number is generated everytime get_roll
method is called.
For the examples listed in your question:
Example 1
qs
is a class variable, and thus only gets evaluated once (which is why you see the "caching" behavior). Subsequent calls to get_queryset
returns the same qs
variable that was initially evaluated.
Example 2
You didn't override get_queryset
, which means ListView.get_queryset
implementation is used.
Django's ListView.get_queryset
copies the queryset
before evaluating it - which is why you don't see "caching". However, because the queryset is copied, the effects from your for loop is thrown away.
Example 3
This is generally the correct way to write your code. You should write your methods like this if you don't want to see "caching" behavior.
Upvotes: 4