Improved queryset handling and docs for (Single|Multiple)ObjectMixin.

This commit is contained in:
Loic Bistuer 2013-08-09 17:31:17 +07:00
parent 8442268869
commit f8a6a4eba1
4 changed files with 42 additions and 14 deletions

View File

@ -57,19 +57,23 @@ class SingleObjectMixin(ContextMixin):
def get_queryset(self):
"""
Get the queryset to look an object up against. May not be called if
`get_object` is overridden.
Return the `QuerySet` that will be used to look up the object.
Note that this method is called by the default implementation of
`get_object` and may not be called if `get_object` is overriden.
"""
if self.queryset is None:
if self.model:
return self.model._default_manager.all()
else:
raise ImproperlyConfigured("%(cls)s is missing a queryset. Define "
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__
})
return self.queryset._clone()
}
)
return self.queryset.all()
def get_slug_field(self):
"""

View File

@ -2,6 +2,7 @@ from __future__ import unicode_literals
from django.core.paginator import Paginator, InvalidPage
from django.core.exceptions import ImproperlyConfigured
from django.db.models.query import QuerySet
from django.http import Http404
from django.utils.translation import ugettext as _
from django.views.generic.base import TemplateResponseMixin, ContextMixin, View
@ -22,18 +23,25 @@ class MultipleObjectMixin(ContextMixin):
def get_queryset(self):
"""
Get the list of items for this view. This must be an iterable, and may
be a queryset (in which qs-specific behavior will be enabled).
Return the list of items for this view.
The return value must be an iterable and may be an instance of
`QuerySet` in which case `QuerySet` specific behavior will be enabled.
"""
if self.queryset is not None:
queryset = self.queryset
if hasattr(queryset, '_clone'):
queryset = queryset._clone()
if isinstance(queryset, QuerySet):
queryset = queryset.all()
elif self.model is not None:
queryset = self.model._default_manager.all()
else:
raise ImproperlyConfigured("'%s' must define 'queryset' or 'model'"
% self.__class__.__name__)
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__
}
)
return queryset
def paginate_queryset(self, queryset, page_size):

View File

@ -63,6 +63,14 @@ MultipleObjectMixin
A ``QuerySet`` that represents the objects. If provided, the value of
``queryset`` supersedes the value provided for :attr:`model`.
.. warning::
``queryset`` is a class attribute with a *mutable* value so care
must be taken when using it directly. Before using it, either call
its :meth:`~django.db.models.query.QuerySet.all` method or
retrieve it with :meth:`get_queryset` which takes care of the
cloning behind the scenes.
.. attribute:: paginate_by
An integer specifying how many objects should be displayed per page. If

View File

@ -23,6 +23,14 @@ SingleObjectMixin
A ``QuerySet`` that represents the objects. If provided, the value of
``queryset`` supersedes the value provided for :attr:`model`.
.. warning::
``queryset`` is a class attribute with a *mutable* value so care
must be taken when using it directly. Before using it, either call
its :meth:`~django.db.models.query.QuerySet.all` method or
retrieve it with :meth:`get_queryset` which takes care of the
cloning behind the scenes.
.. attribute:: slug_field
The name of the field on the model that contains the slug. By default,