使用Django的QuerySet从2个不同的表中检索值

3
以下模型适用:
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

我希望获取所有名为“豪华”的比萨饼及其相应配料的比萨饼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 Queryset相应的想法?如果上述内容还不够具有挑战性,我还希望按名称对所得配料进行排序。
2个回答

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),
]

现在有不同的方法来设置数据,使用列表、元组和字典,但我认为你明白如何做到这一点。


很好,这个问题和https://dev59.com/xXVD5IYBdhLWcg3wJIAK一起帮助我解决了我的问题。 - Thierry Lam

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

然后您可以使用字典获取披萨的配料。


我也有那个解决方案,不过我在想是否有更优雅的方法,因为我还想按名称对配料进行排序。 - Thierry Lam
可能有更优雅的方法来实现这个。排序不是问题: toppings = list(toppings) toppings.sort() - Gerald Senarclens de Grancy
使用这个解决方案,配料将按照披萨进行排序,我的目标是获得豪华披萨所有配料的全局排序列表。 - Thierry Lam
如果您将豪华披萨的所有配料以如上所述的列表形式拥有并对此列表进行排序,则这是所有配料的“全局”排序列表。如果您想尝试一些“更优雅”的东西,您可以获取每个匹配披萨的配料集,并将此集合与总集合合并。不过,这似乎对比萨和配料没有任何好处。现在我要去睡觉了,明天再回来查看。 - Gerald Senarclens de Grancy
那么我如何获取每个配料对应的披萨ID呢? - Thierry Lam
我想我终于明白你想要什么了。如果一开始有其他我没理解对的地方,请告诉我 :) - Gerald Senarclens de Grancy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接