I have a Video object with two ManyToMany fields. Each will contain a list of Users. I’m wondering how important it is to optimize so that there is only one db call when accessing a Video – or if there’s even a way to do that. Also – i’ll only be using the count of each of these ManyToMany fields – is it ‘cheaper’ to call Count() than to get the entire list then do ‘length’?.
For example:
class Video(models.Model):
...
dislikes = models.ManyToManyField(User, null=True)
likes = models.ManyToManyField(User, null=True)
...
In my template for rendering a particular video object – I need the count for each of likes and dislikes. What’s the performance optimal way to do that? It seems to me calling count() which results in two extra db calls is the best – but I’m not sure…
From the documentation:
“Don’t use len() on QuerySets if all you want to do is determine the number of records in the set. It’s much more efficient to handle a count at the database level, using SQL’s SELECT COUNT(*), and Django provides a count() method for precisely this reason.”
There is another way you may want to go, instead of using count() as a separate operation, you may want to annotate the QuerySet with the count of likes/dislikes. Something like:
This will get a Video object with
num_likesandnum_dislikesfields. You could usefilter()orall()instead ofget()to get multiple videos, each with anum_likesandnum_dislikesfield. In your template, you would have{{ video.num_likes }}and{{ video.num_dislikes }}to show these two annotated fields.