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

问题描述:

我对Django没有太多的经验(我使用的是1.3),所以我在脑海里感觉这是一个愚蠢的问题......但无论如何:只获取与Django查询集相关的模型

我有机型是这样的:

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,但我只是想从我的queryset中返回一个条目。 我知道我可以在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查询,因为有些产品是公开的,不要”不用为了买,但我还是要一一列举了,他们会不会被查询对OrderProduct

  2. 我期待的结果返回的产品列表,与自己的订购数据一起(的情况下,他们有它)。在JSON中,它看起来有点像这样

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

感谢

+0

而不是'Product1.orderproduct_set.all()',它是否工作,如果你做'Product1.orderproduct_set.filter(order__user__id = 2)'? – 2013-03-01 20:17:39

我会得到与产品1 OrderProduct的每个条目,但我只是想 从我的查询集的一个返回。

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

如果你想要一个特定OrderProduct,那么你应该过滤为,然后访问该车型环比上涨,像这样:

op.productop.order

+0

感谢您的回复,但它可能不适合我。查看帖子上的修改。 – Gabe 2013-03-01 20:05:08

我会建议的方法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 
+0

'select_related'不适用于多对多关系。所以这种情况下的好处可能不会那么好,而'first_result.product.name'会导致额外的查询。 – 2013-03-01 19:35:15

+0

@DanHoerst是的,但是由于我们选择的是“链接”模型,而不是M2M关系加入的模型......这将起作用。查询的数量将下降到一个。 – Matt 2013-03-01 19:44:38

+0

我已经添加了一些代码,以显示正在运行的查询的数量。 – Matt 2013-03-01 19:48:58