gpt4 book ai didi

django - 了解多值字段的 order_by (Django)

转载 作者:行者123 更新时间:2023-12-04 08:27:11 24 4
gpt4 key购买 nike

已阅读 django docs on order_by 有一个注释/警告(如果我理解正确的话)说:

  • 如果您使用多值字段对查询集进行排序,则该查询集中具有多个相关项的每个元素都将多次添加到由 order_by 创建的结果查询集中。 .

  • 我尝试用一​​个基本示例对此进行测试:
    最小可重复示例
    class Pizza(models.Model):
    name = models.CharField(max_length=100)
    toppings = models.ManyToManyField('Topping', through='PizzaToppings')

    class PizzaToppings(models.Model):
    pizza = models.ForeignKey('Pizza', on_delete=models.CASCADE, related_name="pizza_toppings")
    topping = models.ForeignKey('Topping', on_delete=models.CASCADE, related_name="pizzas_with_topping")
    amount = models.IntegerField()

    class Meta:
    ordering = ["amount",]

    class Topping(models.Model):
    ingredient = models.CharField(max_length=100)
    然后
    >>> p1 = Pizza.objects.create(name="Cheese and Tomato")
    >>> p2 = Pizza.objects.create(name="Pepperoni")
    >>> cheese = Topping.objects.create(ingredient="Cheese")
    >>> tomato = Topping.objects.create(ingredient="Tomato puree")
    >>> p1.toppings.add(cheese, through_defaults={"amount":4})
    >>> p1.toppings.add(tomato, through_defaults={"amount":3})
    >>> p2.toppings.add(cheese, through_defaults={"amount":2})
    >>> p2.toppings.add(tomato, through_defaults={"amount":1})
    到目前为止,很正常。但这就是事情变得困惑的地方:
    >>> q1 = Topping.objects.all()
    <QuerySet [<Topping: Topping object (1)>, <Topping: Topping object (2)>]>
    >>> q2 = p1.toppings.all()
    <QuerySet [<Topping: Topping object (1)>, <Topping: Topping object (2)>]>
    >>> q1.order_by("pizzas_with_topping")
    <QuerySet [<Topping: Topping object (2)>, <Topping: Topping object (1)>, <Topping: Topping object (2)>, <Topping: Topping object (1)>]>
    >>> q2.order_by("pizzas_with_topping")
    <QuerySet [<Topping: Topping object (2)>, <Topping: Topping object (1)>]>
    问题
    从上面可以看出,查询集在它们包含的元素方面是相同的。但是当一个 q1被命令我们得到文档中描述的行为。在 q2我们没有得到那种行为。大概这是因为 django 正在做一些聪明的事情,因为查询集关注与 p1 相关的浇头。 .
    问题
    “幕后”究竟发生了什么来强制执行这种行为?查询集是相同的(如果我理解正确的话),那么为什么 order_by两个查询集的行为不同。

    最佳答案

    这两个查询集是不同的。第一个查询集代表一个查询,如:

    -- q1
    SELECT *
    FROM topping
    q2 表示的查询好像:
    -- q2
    SELECT *
    FROM topping
    INNER JOIN pizzatoppings ON pizzatoppings.topping_id = topping.id
    WHERE pizzatoppings.pizza_id = id-of-pizza
    如果您随后执行 .order_by('pizzas_with_topping') ,那么你就创建了一个 JOINPizzaToppings的 table 上模型,因此您可以按该表的主键进行排序。对于第一个查询集,这看起来像:
    -- q1.order_by('pizzas_with_topping')
    SELECT *
    FROM topping
    LEFT OUTER JOIN pizzatoppings ON pizzatoppings.topping_id = topping.id
    ORDER BY pizzatoppings.id
    对于后者,您可以过滤已经存在的连接:
    -- q2.order_by('pizzas_with_topping')
    SELECT *
    FROM topping
    INNER JOIN pizzatoppings ON pizzatoppings.topping_id = topping.id
    WHERE pizzatoppings.pizza_id = id-of-pizza
    ORDER BY pizzatoppings.id
    因此,这意味着如果相同的配料用于多个比萨饼,对于 q1 ,每次比萨都会出现,而对于 q2我们已经对披萨进行了过滤,因此检索每个 Topping对于那个披萨,而不是其他的。

    关于django - 了解多值字段的 order_by (Django),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65205694/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com