使用Django的QuerySet从两个不同表中获取值

3 投票
2 回答
4832 浏览
提问于 2025-04-15 14:22

对于以下模型:

class Topping(models.Model):
    name = models.CharField(max_length=100)

class Pizza(models.Model):
    name = models.CharField(max_length=100)
    toppings = models.ManyToManyField(Toppping)

我的数据看起来像这样:

披萨和配料表连接在一起:

ID  NAME        TOPPINGS
------------------------------------
1   deluxe      topping_1, topping_2
2   deluxe      topping_3, topping_4
3   hawaiian    topping_1

我想要获取所有名为 deluxe 的披萨的ID,以及它们对应的配料。我的期望结果是:

1   topping_1
1   topping_2
2   topping_3
2   topping_4

连接表是:

pizza_toppings
--------------
id    
pizza_id    
topping_id

这是我想要实现的SQL等价语句:

SELECT p.id, t.name
FROM pizza_toppings AS pt
INNER JOIN pizza AS p ON p.id = pt.pizza_id
INNER JOIN topping AS t ON t.id = pt.topping_id
WHERE p.name = 'deluxe'    

有没有人知道对应的Django查询集应该是什么样的?如果上面的内容不够挑战的话,我还想按名称对结果中的配料进行排序。

2 个回答

0

如果你想要获取一款披萨,但它有一个特定的配料,直接的方法是没有的。你可以这样做:

pizzas = topping.pizza_set.all()

遍历所有带有这个配料的披萨,或者如果这个配料只出现在一款名为“豪华”的披萨上,你也可以这样做:

pizza = topping.pizza_set.get(name="deluxe")

一旦你有了这个配料,你可以把披萨和配料存放在一个元组列表或者字典里(如果没有重复的配料的话):

toppings = {}
pizzas = Pizza.objects.filter(name="deluxe")
for pizza in pizzas:
    for topping in pizza.toppings.all():
        toppings[topping.name] = pizza.name
sorted_toppings = toppings.keys()
sorted_toppings.sort()

这样,你就可以通过字典来找到某个配料对应的披萨了。

2

我觉得这个问题没有一个简单的解决办法,因为你需要从两个不同的模型中获取数据。根据你的数据结构,你可能想用select_related,这样可以避免每次都去数据库查询所有的配料。为了达到你想要的结果,我会这样做:

result = []
pizzas = Pizza.objects.select_related().filter(name='deluxe')
for pizza in pizzas:
    for toppings in pizza.toppings.all():
        result.append((pizza.pk, topping.name))

这样会生成:

[
    (1, topping_1),
    (1, topping_2),
    (2, topping_3),
    (2, topping_4),
]

现在有很多种方法来设置数据,比如使用列表、元组和字典,但我想你已经明白了怎么做了。

撰写回答