简体   繁体   English

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

[英]Getting only the models related to a Django queryset

I don't have much experience with Django (I'm using 1.3) so I have the feeling on the back of my head that this is a dumb question... But anyway: 我没有使用Django的丰富经验(我使用的是1.3),所以我感到这是一个愚蠢的问题……但是无论如何:

I have models like this: 我有这样的模型:

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

And let's say I do some query like this 假设我做这样的查询

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

So I'd get all the products that User2 bought (let's say it's just Product1 ). 因此,我将获得User2购买的所有产品(假设它只是Product1 )。 Cool. 凉。 But now I want the expiration for that product, but if I call Product1.orderproduct_set.all() I'm gonna get every entry of OrderProduct with Product1 , but I just want the one returned from my queryset. 但是现在我想要该产品的到期时间,但是如果我调用Product1.orderproduct_set.all()我将获得与Product1OrderProduct每个条目,但我只想从我的查询集中返回一个条目。 I know I can just run a different query on OrderProducts, but that would be another hit on the database just to bring back data the query I ran before can already get. 我知道我可以在OrderProducts上运行不同的查询,但这将是对数据库的另一次打击,只是要带回我之前运行的查询已经可以获取的数据。 .query on it gives me: .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

If I could SELECT * instead of specific fields I'd have all the data that I need in one query. 如果我可以SELECT *而不是特定字段,那么我将在一个查询中拥有所有需要的数据。 Is there anyway to build that query and get only the data related to it? 无论如何,有没有建立该查询并仅获取与此查询有关的数据?

EDIT I feel I need to clarify some points, I'm sorry I haven't been clearer: 编辑我觉得我需要澄清一些要点,对不起,我还没有更清楚:

  1. I'm not querying against OrderProduct because some products are public and don't have to be bought but I still have to list them, and they'd not be returned by a query against OrderProduct 我不是针对OrderProduct查询,因为某些产品是公开的,不必购买,但是我仍然必须列出它们,并且针对OrderProduct的查询不会返回它们

  2. The result I'm expecting is a list of products, along with their Order data (in case they have it). 我期望的结果是产品列表以及它们的订单数据(如果有的话)。 In JSON, it'd look somewhat like this 在JSON中,它看起来像这样

    [{id: 1, order: 1, expiration: 2013-03-03, public: false}, {id: 1, order: , expiration: , public: true [{id:1,订单:1,有效期:2013-03-03,public:false},{id:1,order :、有效期:,public:true

Thanks 谢谢

I'm gonna get every entry of OrderProduct with Product1, but I just want the one returned from my queryset. 我将使用Product1获取OrderProduct的每个条目,但我只想从我的查询集中返回一个条目。

You just want which "one"? 您只想要哪个“一个”? Your query is filtering on the Product model, so all Users , Orders , and OrderProducts associated with each of the Products in the returned queryset will be accessible. 您的查询正在根据Product模型进行过滤,因此与返回的查询集中的每个Products相关联的所有UsersOrdersOrderProducts都是可访问的。

If you want one specific OrderProduct , then you should be filtering as op = OrderProduct.objects.filter(xxxxx) and then accessing the models up the chain like so: 如果您想要一个特定的OrderProduct ,那么您应该按照op = OrderProduct.objects.filter(xxxxx)进行过滤,然后按如下方式访问模型链:

op.product , op.order , etc. op.productop.order

I would have suggested the method prefetch_related , but this isn't available in Django 1.3. 我会建议方法prefetch_related ,但是在Django 1.3中不可用。

Dan Hoerst is right about selecting from OrderProduct , but that still hits the database more than necessary. Dan Hoerst可以从OrderProduct选择是正确的,但这仍然对数据库造成了不必要的影响。 We can stop that by using the select_related method. 我们可以使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM