This is probably a silly question, but for some reason I just cannot find a way to do this:
I am working on a recommendation engine in Django, which recommends movies based on the similarities between your taste and other users' tastes. Since every database access takes time, I try to use bulk methods as much as possible. However, at one point I need to get the movie that is associated with a certain vote, and I just cannot figure out how to do this in bulk:
The relevant models are:
class Movie(models.Model):
id = models.AutoField(primary_key=True)
...
voters = models.ManyToManyField(Voter)
...
and
class MovieVote(models.Model):
rating = models.FloatField()
weight = models.FloatField()
voter = models.ForeignKey(Voter, on_delete=models.CASCADE, null=True)
movie = models.ForeignKey(Movie, on_delete=models.CASCADE, null=True)
...
And the one line that currently takes 80%(!) of the time of the whole recommendation process is:
for otherVote in listOfOtherVotes:
...
movie = otherVote.movie
...
Is there any way to look up the foreign key "movie" for the whole list of votes at once? And ideally return it as a dictionary that maps each vote to the movie?
CodePudding user response:
If listOfOtherVotes
is a QuerySet
, you can use .select_related(…)
[Django-doc] to make a LEFT OUTER JOIN
in the query, and thus fetch the details of the related .movie
s in the same query, thus avoiding to fetch each .movie
with an extra query:
for otherVote in listOfOtherVotes.select_related('movie'):
# …
movie = otherVote.movie
# …