class IncomeStream(models.Model):
product = models.ForeignKey(Product, related_name="income_streams")
from_date = models.DateTimeField(blank=True, null=True)
to_date = models.DateTimeField(blank=True, null=True)
value = MoneyField(max_digits=14, decimal_places=2, default_currency='USD')
class Product(models.Model):
...
class Sale(models.Model):
product = models.ForeignKey(Product, related_name="sales")
created_at = models.DateTimeField(auto_now_add=True)
...
使用上述模型,假設我想使用 .s 為某些Sales添加一個值.annotate。
這個值被稱為cpa(每行動成本):CPA是值的IncomeStream,其from_date與to_date包括出售created_at在他們的范圍內。
此外, from_date 和 to_date 都是可為空的,在這種情況下,我們假設它們意味著無窮大。
例如:
<IncomeStream: from 2021-10-10 to NULL, value 10$, product TEST>
<IncomeStream: from NULL to 2021-10-09, value 5$, product TEST>
<Sale: product TEST, created_at 2019-01-01, [cpa should be 5$]>
<Sale: product TEST, created_at 2021-11-01, [cpa should be 10$]>
我的問題是:是否可以僅使用 Django ORM 和注釋來撰寫所有這些條件?如果是,如何?
我知道 F 物件可以遍歷這樣的關系:
Sale.objects.annotate(cpa=F('product__income_streams__value'))
但是,我究竟可以在哪里撰寫所有邏輯來確定income_stream它應該value從中選擇哪個特定?
請假設沒有收入流具有相同產品的重疊日期,因此上述規格永遠不會導致沖突。
uj5u.com熱心網友回復:
這樣的事情應該讓你開始
subquery = (
IncomeStream
.objects
.values('product') # group by product primary key i.e. product_id
.filter(product=OuterRef('product'))
.filter(from_date__gte=OuterRef('created_at'))
.filter(to_date__lte=OuterRef('created_at'))
.annotate(total_value=Sum('value'))
)
然后用子查詢
Sale
.objects
.annotate(
cpa=Subquery(
subquery.values('total_value')
) # subquery should return only one row so
# so just need the total_value column
)
如果我自己沒有機會在 shell 中玩這個,我不是 100%。無論如何它應該很接近。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/351590.html
標籤:姜戈 django-orm
下一篇:我的網頁有時會忽略我的css檔案
