How to optimise similar queries in Django? - django

Often, I end up using several similar queries in my Django views, with one varying lookup field.
This accumulate easily, and lead to severe impacts on page load times. How can one go about optimising this?
{
"pg1": Product.objects.filter(groups__group="pg1")[:5],
"pg2": Product.objects.filter(groups__group="pg2")[:5],
"pg3": Product.objects.filter(groups__group="pg3")[:5],
"pg4": Product.objects.filter(groups__group="pg4")[:5],
}

If I understand properly you are writing query for each page? what happens when you have 100's of pages? No, That's not the way you do it!
Use django.core.paginator in django which helps you manage pagination for your views.
More information could be found here
https://docs.djangoproject.com/en/2.1/topics/pagination/

Related

Slow Django Admin change view

I've a model with approximately 150K rows.
It takes 1.3s to render the ListView for this model.
When I click the change link in the ListView I takes almost 2 minutes to render the change view.
Other models have normal render times for the edit view.
Any ideas how to speed this up?
Your best bet is to limit the number of returned rows and implement some type of pagination in your application.
Django conveniently implements a type of pagination
First of all, ask yourself these questions:
Do you have much work with your data in templates?
Can I do this work in a backend and in a template only render it?
Do I use pagination?
As I know pagination in Django implemented with LIMIT and OFFSET sql statements, which work not so quickly when you're having many pages. In our projects, we wrote a row SQL for this purpose which works a little bit faster.
Also, you can install Django Debug Toolbar which can show you what statements django ORM is executing and measure time.

Caching a list of Django comments

I have a site which uses the standard Django comments (well, a subclass of that, but mostly the same). I want to cache the list of comments that's rendered on each page, as that's quite a big and slow query. But, while I know how to cache individual querysets, I can't see how best to do it for the comments app.
It looks like the querysets for these lists of comments are generated in the BaseCommentNode templatetag. So I can't see an easy way to see if there's a cached version of that QS and return that if so... what's my best way of nicely caching this query?
(I'm also caching every page for all logged-out users, with a 5 minute expiry, but think my site would benefit from caching queries like this for a longer period.)

Django passing querysets between pages

I have a view which does a pretty heavy query on three separate databases and outputs the count of each query into a template. From the the user can go to one of the three results and get the detailed results. I don't want to repeat myself in my views and I want to maximize performance, so my question is what is the best way to achieve this result?
Can I pass a queryset to another page (get or post)?
Should I save the queryset in a session (I am not currently using session for this project as it is fully public)
Or is there a better way?
I know this is not a highly specific question, but I would appreciate any advice on this (I'm guessing - not uncommon) situation.
From my experience, I think saving your result on session is a good and simple solution.
Save the result of the querysets to the session. When I say to save the results, what I mean is to run list() on it to execute them, and then store the resulting list in request.session.
sounds like you want to have a look at caching

Django sortable many to many relationship?

I want to set up a many to many relationship between two models, Gallery and Image. I would like to be able to sort them in the site admin in order to change the order the images appear in a gallery on the frontend.
Is there anything built into Django which will help me do this?
I don't want to reinvent the wheel!
Any advice appreciated.
Thanks.
Nothing built-in, no. There's order_with_respect_to, but that's for ForeignKeys and doesn't really expose any functionality in the admin.
A quick Google reveals django-sortedm2m, which I haven't used but is by Gregor Müllegger, who's contributed a fair amount to Django, so is likely to be reliable.

Django project design question

I have just started to work on a django project( and learn django at the same time) and I came across some design questions that I can't really answer with my limited knowledge so I decided to ask it here. anyway Here is the questions:
1) where would you put raw queries. is it ok to put row queries in view.py files? My personal opinion is to put them only in models.py files.
2) where can you query db? can you call query methods in models.py, views.py, templates? I think they should be in models.py or views.py but not in templates. specifically calls like "MyModel__attribute_set__all" should not be used in templates.
Since I am new in django (and python) I am not really sure if I have the right idea about this. I appreciate for any feedback.
Sounds like you're on a good path already.
I try to:
Keep my views slim, in terms of code, and my models fat
keep my templates even slimmer and free of database lookups; if I have to do something that hits the DB that for some reason isn't viable to do in the view, I do it via a templatetag or filter so that it can improved and/or cached, and is also easy to find, and is as DRY as a can be
define and execute any raw SQL in the models that use it
where would you put raw queries. is it ok to put row queries in view.py files?
Queries are most commonly seen in the view.py; yes it's ok there.
My personal opinion is to put them only in models.py files.
If you're using the same query a lot then create a "manager" for the model. You'll put the very commonly used querys there. "Only" in there would be making life hard for yourself.
where can you query db?
Usually in views.py; not uncommonly in models.py.
can you call query methods in ... templates?
Technically it is possible but, logically, very strongly discouraged.
I think they should be in models.py or views.py but not in templates
I agree.