I am trying to understand the django rest framework generic API views, the documentation tells me that while overriding methods of the generic views, I shouldn't be accessing the queryset
attribute directly and instead access the get_queryset()
function because apparently the queryset attribute is evaluated only once, what does the get_queryset()
do differently?
Does the queryset attribute ever get updated?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
To further expand, the source code will tell you the truth.
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)
queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request.
queryset = queryset.all()
return queryset
- First it checks queryset is defined
- Second it checks if the queryset specified is an instance of Django's Queryset class
- Third it re-evaluates (makes a database query) the queryset and sets the results
- Fourth it returns the results
The warning about using self.queryset directly is that results are cached when evaluated so further references to this value will not be up to date as opposed of using self.get_queryset().
回答2:
for simple views, the queryset
attribute would quickly get your started. But in real life, normally, we have permissions on models, for example, the default queryset
for a user would be filtered queryset based on request.user. The get_queryset
method would become
def get_queryset(self):
return self.model.objects.filter(user=self.request.user)
the above get_queryset
method is just an example present real-life API design.