在Django中连接查询
我有一个查询,可以从我的头像应用中获取32个头像图片:
newUserAv = Avatar.objects.filter(valid=True)[:32]
我想把这个查询和django的用户模型结合起来,这样我就能得到最近加入的32个有头像的人,并按加入日期排序。
有什么好的方法可以把这两个查询连接起来吗?
这个头像应用是一个可重用的应用,它的模型是:
image = models.ImageField(upload_to="avatars/%Y/%b/%d", storage=storage)
user = models.ForeignKey(User)
date = models.DateTimeField(auto_now_add=True)
valid = models.BooleanField()
需要注意的是,日期字段是头像更新的日期,所以不适合我的需求。
2 个回答
0
你不能把两个不同的基础模型的查询结果合在一起。Django 不允许这样做,如果你试图这么做,它会报错告诉你不能这样。
不过,如果一个模型里有指向另一个模型的外键,那么在你的查询中加上 select_related(),就可以在一次数据库查询中把相关的对象一起取出来,这样你就可以直接使用这些对象,而不用再去数据库查了。
2
你可以在自己的用户类里加一个字段,表示这个用户有头像。这样你就可以很方便地查询了。你可能需要继承用户类或者和 django.contrib.auth.models.User
组合使用。
或者你可以这样做:
from django.utils.itercompat import groupby
avatars = Avatar.objects.select_related("user").filter(valid=True).order_by("-user__date_joined")[:32]
grouped_users = groupby(avatars, lambda x: x.user)
user_list = []
for user, avatar_list in grouped_users:
user.avatar = list(avatar_list)[0]
user_list.append(user)
# user_list is now what you asked for in the first_place:
# a list of users with their avatars
这里假设每个用户只有一个头像。如果你的模型允许每个用户有多个头像,那你就得注意不要存储超过一个头像。
代码片段的解释:
这个代码请求了最近加入的32个用户的头像,并且把相关的用户信息一起请求过来,这样在后面的代码中就不需要再查询数据库了。
头像列表会根据用户进行分组,list
会从生成器 avatar_list
中获取所有项,并把第一个项(应该只有一个)赋值给 user.avatar
。
需要注意的是,这一步不是必须的,你也可以这样做:
for avatar in avatars:
user = avatar.user
不过通过 user.avatar
来访问头像可能会更自然一些。