Using The Results From A Query In BOTH The Templates And The View
In Django, I need to query a table to get some details from the database. I need the results BOTH in the views and in ALL of my templates.
Is there a way to only run this query once?
Here is my current setup if I don't use a context processor:
views.py
:
def collect_important_information():
return SomeModel.objects.filter(parameter=abc)
def homepage(request):
information = collect_important_information()
if information:
do something
context = {"information": information}
return render(request, "index.html", context)
def second_page(request):
information = collect_important_information()
if information:
do something else
context = {"information": information}
return render(request, "second.html", context)
def third_page(request):
information = collect_important_information()
if not information:
do something
context = {"information": information}
return render(request, "third.html", context)
def fourth_page(request):
information = collect_important_information()
context = {"information": information}
return render(request, "third.html", context)
There is a lot of replication here. I can reduce that by using a custom context_processor to insert the "information" variable into each template. Something like this:
custom_context_processor.py:
def site(request):
return { "information": SomeModel.objects.filter(parameter=abc) }
This allows me to reduce my views.py
to this:
def collect_important_information():
return SomeModel.objects.filter(parameter=abc)
def homepage(request):
information = collect_important_information()
if information:
do something
return render(request, "index.html")
def second_page(request):
information = collect_important_information()
if information:
do something else
return render(request, "second.html")
def third_page(request):
information = collect_important_information()
if not information:
do something
return render(request, "third.html")
def fourth_page(request):
return render(request, "fourth.html")
My views is much cleaner. However, if I do that I have to run the database query twice for many of these requests. Once to obtain the database variables I need inside my views.py function (for some condition that takes place, independent from the template), and a second time in the context processor file.
Is there a way to somehow 'centralize' the query and have it run only once, and still inserting it into the template file AND having it available within the function of the view?
Answer
Is there a way to somehow 'centralize' the query and have it run only once, and still inserting it into the template file AND having it available within the function of the view?
QuerySet
s are lazy constructing a queryset will not make a database request, you make a query to the database if you consume the queryset, for example by enumerating over it, calling str(…)
, repr(…)
and len(…)
on it, check its truthiness with bool(…)
or in an if
/elif
clause.
If you thus use a context processor that passes the filtered queryset to the template, and you do not use the queryset in a way described above, that will not make a query. Furthermore if the data is passed to the context, it will override the data in the context processor. So you can add it to the context in case you already evaluated it in the view, to prevent making a second database query you thus override this in the context, such that there is no reference to the "other" queryset, and the result is reused.
You need to be careful not to construct a new query if the one is evaluated. For example if qs
is an evaluated queryset, you should work with qs
again, if you work with qs.all()
this will make a new QuerySet
that will then make a query to the database.
Related Questions
- → Django, code inside <script> tag doesn't work in a template
- → Uncaught ReferenceError: Parent is not defined
- → React - Django webpack config with dynamic 'output'
- → Put a Rendered Django Template in Json along with some other items
- → Implement shopify templates in django
- → Python Shopify API output formatted datetime string in django template
- → How to avoid being crawled/penalized by Google
- → Django: Identify the urls that provide duplicate content and set a canonical link
- → Shopify app: adding a new shipping address via webhook
- → Jquery Modal Confirmation on Django form submit for deletion of object
- → changing the size of an image with css
- → shopify_auth multi store session handling
- → How to use Shopify Python API RecurringApplicationCharge