如何检索一组对象,按其他对象的字段过滤和排序,所需对象是外键?
Posted
技术标签:
【中文标题】如何检索一组对象,按其他对象的字段过滤和排序,所需对象是外键?【英文标题】:How to retrieve a set of objects, filtered and ordered by fields of other objects, for which the desired object is a foreign key? 【发布时间】:2016-06-03 06:28:45 【问题描述】:将标题改写为我的问题的上下文:如何检索一组食物,按其他对象的字段过滤和排序,食物对象是外键?
我有以下型号:
class Food(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
description = models.CharField(max_length=200, blank=True)
class DayOfFood(models.Model):
user = models.ForeignKey(User)
date = models.DateField()
unique_together = ("user", "date")
class FoodEaten(models.Model):
day = models.ForeignKey(DayOfFood, on_delete=models.CASCADE)
food = models.ForeignKey(Food, on_delete=models.CASCADE)
servings = models.FloatField(default=1)
我希望能够检索给定用户最近吃的食物。这个食物集合将被传递给一个模板,因此它必须是一个 QuerySet 以允许模板循环遍历食物对象。
这是我走了多远
days = DayOfFood.objects.filter(user=request.user)
foodeatens = FoodEaten.objects.filter(day__in=days)
foodeatens = foodeatens.order_by('day__date')
现在感觉就像我快到了,我想要的所有食物都包含在生成的 QuerySet 中的 FoodEaten 对象中。我不知道如何使用“for ... in:”来获取食物对象并将它们存储在 QuerySet 中。有没有办法执行 foreach 或映射到 QuerySet?
我不想重写模板来接受 FoodEaten 对象,因为模板被其他视图使用,它们只是将食物对象传递给模板。
解决办法
尚旺的回答帮助我编写了解决问题的代码:
days = DayOfFood.objects.filter(user=request.user)
foods = Food.objects.filter(
foodeaten__day__in=days,
foodeaten__day__user=request.user) \
.order_by('-foodeaten__day__date')
【问题讨论】:
【参考方案1】:这可以使用关系链来完成:
Food.objects.filter(foodeaten__day__in=days,
foodeaten__day__user=request.user) \
.order_by('foodeaten__day__date')
顺便说一句,我不知道您为什么在多个型号Food
和DayOfFood
上都有user
。如果你真的需要他们两个的用户关系,也许让字段名称更明确地说明用户在每个模型中的角色,否则你很快就会混淆。
【讨论】:
谢谢!您的代码帮助我了解如何在“其他”方向上遵循外键关系。您的代码中有一个错误,第一个过滤器参数是我在添加到原始问题帖子的解决方案中更正的。 哦,我忘了回答为什么 Food 和 DayOfFood 都需要用户字段。那是因为在我的程序中,食物不会在用户之间共享。用户每天只能吃属于他的食物。以上是关于如何检索一组对象,按其他对象的字段过滤和排序,所需对象是外键?的主要内容,如果未能解决你的问题,请参考以下文章