When to use get, get_queryset, get_context_data in Django?
They indeed do different things.
get()
This is a top-level method, and there's one for each HTTP verb - get()
, post()
, patch()
, etc. You would override it when you want to do something before a request is processed by the view, or after. But this is only called when a form view is loaded for the first time, not when the form is submitted. Basic example in the documentation. By default it will just render the configured template and return the HTML.class MyView(TemplateView):
# ... other methods
def get(self, *args, **kwargs):
print('Processing GET request')
resp = super().get(*args, **kwargs)
print('Finished processing GET request')
return resp
get_queryset()
Used by ListView
s - it determines the list of objects that you want to display. By default, it will just give you all for the model you specify. By overriding this method you can extend or completely replace this logic. Django documentation on the subject.class FilteredAuthorView(ListView):
template_name = 'authors.html'
model = Author
def get_queryset(self):
# original qs
qs = super().get_queryset()
# filter by a variable captured from url, for example
return qs.filter(name__startswith=self.kwargs['name'])
get_context_data()
This method is used to populate a dictionary to use as the template context. For example, ListView
s will populate the result from get_queryset()
as author_list
in the above example. You will probably be overriding this method most often to add things to display in your templates.def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data['page_title'] = 'Authors'
return data
And then in your template, you can reference these variables.<h1>{{ page_title }}</h1>
<ul>
{% for author in author_list %}
<li>{{ author.name }}</li>
{% endfor %}
</ul>
Now to answer your main question, the reason you have so many methods is to let you easily stick your custom logic with pin-point accuracy. It not only allows your code to be more readable and modular, but also more testable.
The documentation should explain everything. If still not enough, you may find the sources helpful as well. You'll see how everything is implemented with mixins which are only possible because everything is compartmentalized.
How to pass value from get_queryset() to get_context_data()
When a list view is paginated, you can access the paginator in the template context with paginator
.
Therefore you can access the length of the entire (unpaginated) queryset with:
{{ paginator.count }}
As an aside, your get_queryset
method should always return a list or a queryset. When search_text
is not specified, you could return an empty queryset, Store.objects.none()
.def get_queryset(self):
...
if search_text:
...
else:
search_stores = Store.objects.none()
return search_stores
I would also avoid looping over the queryset to set store.mKey = store.mKey.split(' ')
. This will evaluate the entire queryset, not just the page that you are displaying. It might be better to add a property to your model, for example:class Store(models.Model):
...
@property
def mkey_list(self):
return self.mKey.split(' ')
Then in your template you can do something like: {% for key in store.mkey_list %}
{{ key }}
{% endfor %}
Django: get_queryset after get_context_data
Just filter inside of get_queryset method
def get_queryset(self, *args, **kwargs):
queryset = super().get_queryset(*args, **kwargs)
search = self.request.GET.get('buscar', None)
queryset = queryset.filter(engineer=self.request.user)
if search:
queryset = queryset.filter(
Q(project_title__icontains=search) |
Q(category__title__icontains=search)
).distinct()
return queryset
get context data in get_queryset
for Listview get_quersyset() is called before get_contex_data() , hence getting context data is not possible in get_queryset()
How to define get_queryset, get_context_data in a django view?
First of all you need to establish a ForeignKey
relationship between your models.
#models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length = 250)
author = models.ForeignKey(Author, related_name="books")
def __unicode__(self):
return self.Title
Now in your view you should be able to retrieve your list of authors by overriding the get_queryset
method like this:#views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import TemplateView, ListView
from .models import Author
class BooksByAuthorList(ListView):
model = Book
template_name = 'instancias/pruebas.html'
def get_queryset(self):
return Author.objects.prefetch_related("books").all()
With just the above view you should be able to have in your template:<ul>
{% for author in object_list %}
<li>{{author.name}}</li><ul>
{% for book in author.books.all %}
<li>book.title</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
Now say you want to customize that so that instead of the generic object_list
the context variable was instead something sensible in the domain like authors
.Just augment your view like this:
class BooksByAuthorList(ListView):
model = Author
template_name = 'instancias/pruebas.html'
context_object_name = 'authors'
def get_queryset(self):
return Author.objects.prefetch_related("books").all()
Note you don't need get_context_data
at all yet. Assuming you'd like to include some additional data you'll just want to override get_context_data
and in this case you'll want to keep the object list that's already in your context by calling the superclasses get_context_data
method first.
Just do:
def get_context_data(self, *args, **kwargs):
# Call the base implementation first to get a context
context = super(BooksByAuthorList, self).get_context_data(*args, **kwargs)
# add whatever to your context:
context['whatever'] = "MORE STUFF"
return context
get_context_data
arguments are determined by your routes. *args
and **kwargs
should probably be replaced with something specific to your view and route in your actual code.
Related Topics
Return List of Items in List Greater Than Some Value
How to Add Trendline in Python Matplotlib Dot (Scatter) Graphs
What's the Difference Between Subprocess Popen and Call (How to Use Them)
How May I Override the Compiler (Gcc) Flags That Setup.Py Uses by Default
Convert Date to Datetime in Python
How to Use Asyncio with Existing Blocking Library
In-Place Type Conversion of a Numpy Array
Filtering a Pyspark Dataframe with SQL-Like in Clause
Create Spark Dataframe. Can Not Infer Schema for Type
How to Pickle a Dynamically Created Nested Class in Python
How to Change a Widget's Font Style Without Knowing the Widget's Font Family/Size
How to Get Windows' Special Folders for Currently Logged-In User