如何检索一组对象,按其他对象的字段过滤和排序,所需对象是外键?

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')

顺便说一句,我不知道您为什么在多个型号FoodDayOfFood 上都有user。如果你真的需要他们两个的用户关系,也许让字段名称更明确地说明用户在每个模型中的角色,否则你很快就会混淆。

【讨论】:

谢谢!您的代码帮助我了解如何在“其他”方向上遵循外键关系。您的代码中有一个错误,第一个过滤器参数是我在添加到原始问题帖子的解决方案中更正的。 哦,我忘了回答为什么 Food 和 DayOfFood 都需要用户字段。那是因为在我的程序中,食物不会在用户之间共享。用户每天只能吃属于他的食物。

以上是关于如何检索一组对象,按其他对象的字段过滤和排序,所需对象是外键?的主要内容,如果未能解决你的问题,请参考以下文章

Django orm总结

如何将一组 java 对象表示为数据库中其他对象的字段?

v-for列表过滤和排序

如何按多个字段对对象数组进行排序?

根据另一个数组和条件过滤一组对象

如何按 C# 中的特定字段对对象列表进行排序?