我对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 *
而不是特定字段,我会在一个查询中获得所需的所有数据。无论如何构建该查询并仅获取与其相关的数据?
修改 我觉得我需要澄清一些观点,对不起,我还不清楚:
我不是要查询OrderProduct
,因为有些产品是公开的而且不需要购买,但我仍然需要列出它们,并且它们不会被{{{{{ {1}}
我期待的结果是产品列表及其订单数据(如果有的话)。在JSON中,它看起来有点像
[{id:1,order:1,expiration:2013-03-03,public:false}, {id:1,order:,expiration:,public:true
由于
答案 0 :(得分:1)
我将使用Product1获取OrderProduct的每个条目,但我只是 想要从我的查询集返回的那个。
你只想要哪个“一个”?您的查询正在对Product
模型进行过滤,因此与返回的查询集中的每个Users
相关联的所有Orders
,OrderProducts
和Products
都可以访问
如果你想要一个特定的OrderProduct
,那么你应该过滤为op = OrderProduct.objects.filter(xxxxx)
,然后像这样访问链上的模型:
op.product
,op.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