I'm pretty new at Django and wondering what is the difference between defining model vs queryset in a generic view like ListView. Here's my code example in my urls.py file for the project:
urlpatterns = patterns('',
url(r'^$', ListView.as_view(
model=Person,
context_object_name='people',
template_name='index.html',
)),
)
I've also used the same this:
urlpatterns = patterns('',
url(r'^$', ListView.as_view(
queryset=Person.objects.all,
context_object_name='people',
template_name='index.html',
)),
)
And received the same result on my view. I'm assuming there are different things you can do with a queryset?
Django's generic views were developed to ease that pain. They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to write too much code.
List View refers to a view (logic) to display multiple instances of a table in the database. We have already discussed the basics of List View in List View – Function based Views Django. Class-based views provide an alternative way to implement views as Python objects instead of functions.
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. Return the context variable name that will be used to contain the data that this view is manipulating.
Custom managers. You can use a custom Manager in a particular model by extending the base Manager class and instantiating your custom Manager in your model. There are two reasons you might want to customize a Manager : to add extra Manager methods, and/or to modify the initial QuerySet the Manager returns.
Using model=Person
or queryset=Person.objects.all
give the same result.
Let's look at the code. A ListView
has the following method:
def get_queryset(self):
"""
Get the list of items for this view. This must be an interable, and may
be a queryset (in which qs-specific behavior will be enabled).
"""
if self.queryset is not None:
queryset = self.queryset
if hasattr(queryset, '_clone'):
queryset = queryset._clone()
elif self.model is not None:
queryset = self.model._default_manager.all()
else:
raise ImproperlyConfigured(u"'%s' must define 'queryset' or 'model'"
% self.__class__.__name__)
return queryset
As you can see, it first looks for self.queryset
and, if that does not exist, for self.model
. So there are two possibilities to specify a list: you can provide a queryset yourself or you can specify a model class (in which case Django will call the all()
method of the default manager, which is objects
).
I'm assuming there are different things you can do with a queryset?
Yes. If you specify a model
, then you get all instances by default. But if you specify a queryset
, you can also call other methods of a model manager, such as Person.objects.children()
which could return only persons with age <= 12
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With