【问题标题】:Filter distinct queryset by fields of a ForeignKey按 ForeignKey 的字段过滤不同的查询集
【发布时间】:2020-12-08 12:06:29
【问题描述】:

(我认为问题的标题远非完美,这可能是我找不到任何有用帮助的原因。欢迎编辑!)

假设以下模型:

class Pizza(models.Model):
    name = models.CharField(max_length = 128)

class Person(models.Model):
    name = models.CharField(max_length = 128)

下一个模型连接连接personpizza,并有一个额外的布尔字段。例如,假设模型存储了每个人最喜欢的比萨饼,布尔字段指示相应的比萨饼是否在每个人的绝对最爱中。

class TopPizzasForPerson(models.Model):
    person = models.ForeignKey(
        Person,
        related_name = 'top_pizzas',
        on_delete = models.CASCADE
    )
    pizza = models.ForeignKey(
        Pizza, on_delete = models.CASCADE
    )
    is_nearly_perfect = models.BooleanField(default = False)

最后一个模型存储某个人吃了某个披萨。

class PizzaPersonDateRelation(models.Model):
    person = models.ForeignKey(
        Person,
        related_name = 'eaten_pizzas',
        on_delete = models.CASCADE
    )
    pizza = models.ForeignKey(Pizza)
    date = models.DateField()

我想要一个列表,其中包含某人吃特定披萨的最后日期。因此,应该出现来自PizzaPersonDateRelationpersonpizza 的所有组合,但如果这种组合多次出现,则只应包括最后一个。目前,我这样做是:

qs = PizzaPersonDateRelation.objects \ 
    .distinct('person', 'pizza') \ 
    .order_by('person', 'pizza', '-date')

我现在的第一个问题是:如何将上述查询集限制为仅包含每个人绝对最喜欢的比萨饼,即TopPizzasForPerson.is_nearly_perfectTrue

这是我在 python 级别而不是数据库级别的操作方式:

[ 
    data for data in qs \
    if data.person.top_pizzas.filter(pizza = data.pizza, is_nearly_perfect = True).exists()
]

第二个问题是:上面的查询集是否可以扩展为包含额外的行,如果某个人绝对最喜欢的比萨饼从未被那个人吃过,则可以使用None for date,即,如果在TopPizzasForPerson 中存在某个personpizza 的条目,而is_nearly_perfectTrue,但personpizza 的组合中不存在PizzaPersonDateRelation 的条目

【问题讨论】:

    标签: django django-queryset


    【解决方案1】:

    这个查询应该得到你想要的。

    PizzaPersonDateRelation.objects \
    .filter(person__top_pizzas__is_nearly_perfect=True) \
    .distinct('person', 'pizza') \ 
    .order_by('person', 'pizza', '-date')
    

    可以使用related_name遍历相关模型。

    【讨论】:

    • 这似乎不是我想要的。假设我们有johnjimmy 作为persons,salamionions 作为pizzas 和john 已选择salami 作为最爱,并且PizzaPersondateRelation 存在于所有四个组合,您的建议将包含john 的所有(不同)值。过滤器似乎选择了任何与 top_pizza-relation 与 is_nearly_perfect = True 的人
    • 您想获取is_nearly_perfectTrue 的所有条目,对吗?
    • 嗯,或多或少。如果personpizza 的组合具有is_nearly_perfect = True 987654339@ 和pizza (在PizzaPersonDateRelation 中),我想获得最新的(datePizzaPersonDateRelation 中) @在TopPizzasForPerson.
    猜你喜欢
    • 2021-12-20
    • 2012-07-10
    • 1970-01-01
    • 2023-01-04
    • 2018-10-28
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    相关资源
    最近更新 更多