【发布时间】:2019-05-26 21:22:37
【问题描述】:
使用 Django 1.11
我有以下型号:
class Vendor(Model):
class Product(Model):
class Pricebook(Model):
class Quote(Model):
vendor = models.ForeignKey(Vendor)
class SKU(Model):
product = models.ForeignKey(Product)
pricebook = models.ForeignKey(Pricebook)
vendor = models.ForeignKey(Vendor)
class SKUPrice(Model):
sku = models.ForeignKey(SKU, related_name="prices")
class LineItem(Model):
quote = models.ForeignKey(Quote, related_name="quote_line_items")
sku = models.ForeignKey(SKU)
这是对我有用的原始查询。
SELECT
qli.quantity,
sku_source.product_id,
sku_dest.id as sku_dest_id,
sku_dest_price.id as sku_dest_price_id
FROM lineitem qli
INNER JOIN sku sku_source ON
qli.sku_id = sku_source.id
LEFT JOIN sku sku_dest ON
sku_dest.pricebook_id = sku_source.pricebook_id AND
sku_dest.product_id = sku_source.product_id
LEFT JOIN skuprice sku_dest_price ON
sku_dest_price.status = 'default' AND
sku_dest_price.sku_id = sku_dest.id
WHERE qli.quotation_id = 40 AND
qli.quantity > 0 AND
sku_dest.vendor_id = 38;
我试过的是:
(the_quote_with_id_as_40
.quotation_line_items
.filter(quantity__gt=0)
.select_related('sku__product')
.values('sku__product__id', 'quantity')
)
这会产生这个查询
SELECT "sku"."product_id", "lineitem"."quantity"
FROM "lineitem"
INNER JOIN "sku" ON ("lineitem"."sku_id" = "sku"."id")
WHERE ("lineitem"."quotation_id" = 40 AND
"lineitem"."quantity" > 0)
这不是我想要的。
我当然可以使用原始查询。但我想知道是否可以使用 ORM。至少,这是为了扩展我的知识。
谢谢。
更新
由于有人要求澄清我的模型,我正在写以下内容。
我有一个 Quote 对象。它允许许多 LineItem 对象。每个 LineItem 与 SKU 和 Quote 是一对多的。
一个 SKU 属于一个价格手册、一个产品和一个供应商。这些关系的描述也可以从上面的代码中收集到。
但为了清楚起见,我将在这里重复。
这种安排使得不同的供应商可以销售一个相同的产品,但它们将显示为不同的 SKU。
这是设计使然。
我们的用例是这样的:用户尝试将特定报价的 LineItems 复制到不同的报价。
在用户的心目中,他们没有能力理解 SKU、LineItem 或产品之间的差异。
这都是他们心中的产品。他们只是希望相同的产品出现在具有相同数量的不同报价中。
挑战是这样的。我们现在有两个引用(要复制的源引用和要复制到的目标引用)。两个报价可能具有相同的供应商。或者他们可能不会。用户希望我的 Django 应用自动满足这两种情况。
所以这意味着我需要在复制之前找出以下内容。
- LineItem 中规定的数量
- LineItem 中所述的产品相对于 SKU
- 查找供应商为目的地报价销售的相应 SKU
- 及其对应的单价
原始查询允许我在一个查询中提取所有 4 条信息。很有效率。
因此你看到我有别名 sku_source 和 sku_dest
这就是为什么我的 WHERE 条件包含 3 个条件:
- 只会复制数量 > 0 的源行项目
- 只会复制来自特定来源报价单的 LineItems
- 仅针对特定供应商(在本例中为目标报价的供应商)的 SKU 将被调查
有可能:
同一产品(针对 SKU)的多个 LineItem 将出现在同一来源报价单中。
目标供应商(即目标报价的供应商)不销售源供应商确实销售的特定产品。因此我使用左连接。这意味着该特定产品不会被复制。
我希望这可以解决问题。
【问题讨论】:
-
感谢您的回复。所以你的观点是有时使用原始查询更好?是这样的吗?
-
@KimStacks Django ORM 是对特定数据库的抽象,但有助于了解您的实际数据库以帮助您。
-
你能澄清一下你的模型吗?您的查询(您声称有效的查询)似乎将 SKU 表加入到自身中,而实际上什么也没做。即
LEFT JOIN sku sku_dest没有多大意义。除非您有多个具有完全相同外键的 SKU 对象。 -
@KimStacks 用文字(而不是查询)解释您想要实现的目标。 ORM 与对象一起工作,那么您需要什么样的对象和什么样的相关数据?