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

时间:2009-09-16 21:00:47

标签: python django django-models

对于以下型号:

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

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

我的数据如下所示:

加入了Pizza和Topping表:

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

我希望获得披萨ID以及所有名为deluxe的披萨的相应配料。我的预期结果是:

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 个答案:

答案 0 :(得分: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),
]

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

答案 1 :(得分:0)

当您从上面的模型获得顶部时,没有直接的方法可以获得比萨饼。你可以做到

pizzas = topping.pizza_set.all()

对于所有披萨或可能的披萨(如果只有一个比萨饼存在于名为“豪华”的披萨上)

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

一旦你有一个打顶。或者,您可以将Pizza和Topping存储在元组或字典列表中(如果没有重复的顶部):

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

然后你可以用字典来获取比萨饼。