我想得到所有相关模型的数据,但我只得到了部分相关数据,为了避免N +1问题,我使用了select_related()和prefetch_related()方法。
起初,我有这些模型:
class OrderList(models.Model):
order_id=models.CharField(max_length=100)
order_status=models.CharField(max_length=100)
class ProductInOrder(models.Model):
order_key=models.ForeignKey(OrderList, on_delete=models.CASCADE, related_name="order_key")
product_id=models.CharField(max_length=100)
product_price=models.CharField(max_length=100)
class MemosInProduct(models.Model):
product_key=models.ForeignKey(ProductInOrder, on_delete=models.CASCADE, related_name="product_key")
memo=models.CharField(max_length=100)
blahblah some codes...
这些模型的一个简短示例是,一个OrderList具有许多ProductInOrder(一对多),一个ProductInOrder具有许多MemosInProduct(一对多)
然后,我在django shell中运行以下代码:
order_list=OrderList.object.select_related("order_key", "product_key").all()
我排除了所有订单数据以及与之结合的所有相关数据(产品、备忘录):* * 除外**
订单列表[0].订单关键字[0].产品关键字[0].备注订单列表[0].订单关键字[0].产品关键字[1].备注订单列表[0].订单关键字[1].产品关键字[0].备注...
但我得到了:输出
select_related中给定的字段名无效:"订单密钥"、"产品密钥"。选项包括:(无)
我也试过这个:
order_list=MemosInProduct.object.select_related("order_key", "product_key").all()
但是输出不匹配。
2条答案
按热度按时间p1tboqfb1#
从Django Documentation
select_related
获取相关对象(外键关系),如果外键存在于模型中,这意味着它获取向前相关的对象。例如:
因为在这个模型中没有正向关系,所以不能使用
select_related
,所以Django会引发错误。select_related中给定的字段名无效:"订单密钥"、"产品密钥"。选项包括:(无)
但是,您可以将
select_related
用于ProductInOrder
和MemosInProduct
,因为ProductInOrder
和MemosInProduct
分别具有order_key
和product_key
的正向关系。对于向后关系(查询模型中不存在外键),应该使用
prefetch_related
。因此,在您的情况下,查询应该是
在这里,您可以看到我还将
product_key
更改为order_key__product_key
,因为product_key
不是OrderList
的相关对象,而是ProductInOrder
的相关对象这只是理论上的,也许你需要在你的查询中使用
Prefetch
。不过,请阅读Django文档了解详细信息。
nfg76nw02#
我会用相反的方法来解决这个问题,检索
MemosInProduct
对象及其相关对象,例如,要用order_status = 'overdue'
获取与OrderList对象相关的所有内容(我猜):在检索对象的循环中,如果跟踪循环中的上一项,则可以知道何时已前进到不同的ProductInOrder或OrderList
或者,您可以构造列表的列表的列表,当传递到要呈现的上下文中时,这在模板语言中很容易实现。
记住,Python赋值是名称绑定,而不是对象复制,所以这类事情是高效的,在循环中,乘积和顺序由
select_related
预取。