Here’s my model design:
class Group(models.Model):
name = models.CharField(max_length=30)
...
class User(models.Model):
name = models.CharField(max_length=50)
...
group = models.ForeignKey(Group)
class Photo(models.Model):
title = models.CharField(max_length=100)
...
user = models.ForeignKey(User)
How can I get a list of all groups, under each group 5 random photos which belong to users belonging to the group?
I tried:
g = Group.objects.all()
for group in g:
r = Photo.objects.filter(user.group=group).order_by('?')[:5]
That is giving:
Django Version: 1.4.3
Exception Type: SyntaxError
Exception Value:
keyword can't be an expression (views.py, line 37)
Exception Location: /PATH/python2.7/site-packages/django/utils/importlib.py in import_module, line 35
Python Executable: /PATH/python
Python Version: 2.7.3
But even if my code worked, I don’t believe it’s the ideal way since it will generate too many queries.
Please help.
The issue is that you can’t use
user.groupsas a keyword argument to the.filter(…)function.Instead, use
user__groups=groupto span the user -> group relationship:The relevant documentation: https://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships
Unfortunately getting rid of the for-loop would be fair fairly tricky, as it would require querying for the top N rows from a
GROUP BYquery… So unless you’ve got a bunch of groups, the Python for-loop is probably the most straight forward way to do it.Now, that said, if performance is important, you’ll probably need to come up with a smarter solution because ordering by
RANDOM()is very slow too…