仅获取与Django查询集相关的模型

时间:2013-03-01 16:21:46

标签: python django django-queryset

我对Django没有多少经验(我使用的是1.3)所以我感觉到这是一个愚蠢的问题...但无论如何:

我有这样的模特:

class User(models.Model):
    name = models.CharField()

class Product(models.Model):
    name = models.CharField()
    public = models.BooleanField()

class Order(models.Model):
    user = models.ForeignKey(User)
    product = models.ManyToManyField(Product, through='OrderProduct')

class OrderProduct(models.Model):
    product = models.ForeignKey(Product)
    order = models.ForeignKey(Order)
    expiration = models.DateField()

让我说我做这样的查询

Product.objects.filter(order__status='completed', order__user____id=2)

所以我会得到User2买的所有产品(让我们说它只是Product1)。凉。但是现在我希望该产品过期,但是如果我调用Product1.orderproduct_set.all()我将OrderProduct的所有条目都带有Product1,但我只想要从我的查询集返回的条目。 我知道我可以在OrderProducts上运行一个不同的查询,但这将是数据库上的另一个问题,只是为了将数据恢复到我之前已经运行的查询。 .query就可以了:

SELECT "shop_product"."id", "shop_product"."name"
FROM "shop_product"
INNER JOIN "shop_orderproducts" ON ("shop_product"."id" = "shop_orderproducts"."product_id")
INNER JOIN "shop_order" ON ("shop_orderproducts"."order_id" = "shop_order"."id")
WHERE ("shop_order"."user_id" = 2  AND "shop_order"."status" = completed )
ORDER BY "shop_product"."ordering" ASC

如果我可以SELECT *而不是特定字段,我会在一个查询中获得所需的所有数据。无论如何构建该查询并仅获取与其相关的数据?

修改 我觉得我需要澄清一些观点,对不起,我还不清楚:

  1. 我不是要查询OrderProduct,因为有些产品是公开的而且不需要购买,但我仍然需要列出它们,并且它们不会被{{{{{ {1}}

  2. 我期待的结果是产品列表及其订单数据(如果有的话)。在JSON中,它看起来有点像

    [{id:1,order:1,expiration:2013-03-03,public:false},  {id:1,order:,expiration:,public:true

  3. 由于

2 个答案:

答案 0 :(得分:1)

  

我将使用Product1获取OrderProduct的每个条目,但我只是   想要从我的查询集返回的那个。

你只想要哪个“一个”?您的查询正在对Product模型进行过滤,因此与返回的查询集中的每个Users相关联的所有OrdersOrderProductsProducts都可以访问

如果你想要一个特定的OrderProduct,那么你应该过滤为op = OrderProduct.objects.filter(xxxxx),然后像这样访问链上的模型:

op.productop.order

答案 1 :(得分:0)

我建议使用方法prefetch_related,但这在Django 1.3中不可用。

Dan Hoerst对于从OrderProduct进行选择是正确的,但仍然会超出必要的数据库。我们可以使用select_related方法阻止它。

>>> from django.db import connection
>>> len(connection.queries)
0
>>> first_result = OrderProduct.objects.select_related("order__user", "product")
...               .filter( order__status="completed",
...                        order__user__pk=2 )[0]
>>> len(connection.queries)
1
>>> name = first_result.order.user.name
>>> len(connection.queries)
1
>>> product_name = first_result.product.name
>>> len(connection.queries)
1