How to avoid choosing n + 1 in django?

I have a very simple datamodel with a one-to-many relationship between video and comments

class Video(models.Model): url = models.URLField(unique=True) ..... class Comment(models.Model): title = models.CharField(max_length=128) video = models.ForeignKey('Video') ..... 

I want to request a video and capture the entire graphic object (video with all comments). Looking at sql, I see that it makes two choices: one for the video and one for the comments. How to avoid this? I want to make a joint connection and capture everything at once.

Can this be done with django?

+6
source share
3 answers

For ForeignKey, you can use selected_related () :

 Comment.objects.select_related('video').all() 

It will generate only one request, collect comments for you, as well as videos.

For something more complex (like M2M), you need an external application such as unjoinify for optimization, but it uses SQL queries to then return them back to objects.

If this (I) is not convenient for you, you have several alternatives:

+10
source

What you need to do is use select_related in the comment.

Suppose you need to find all videos whose name begins with 'The' and the associated comments

 comments = Comment.objects.filter(video__title__starts_with='The') .select_related('video').all() 

This will load all comments and the corresponding Video object for this comment. You still have to rotate the video to iterate over the video. Use the python function itertools.groupby to perform this operation in memory.

+1
source

See, if you select the appropriate one , it works as you expected, it was made just for this.

0
source

Source: https://habr.com/ru/post/890773/


All Articles