[英]Self-referential aggregation in django
是否可以在Django中編寫自引用聚合?
例如,給定以下模型定義:
from django.db import models
class Match(models.Model):
match_id = models.BigIntegerField(primary_key=True)
start_time = models.DateTimeField()
league = models.ForeignKey(League, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete.models.CASCADE)
我想用先前的匹配數注釋每個Match
對象。 (並最終在其他條件下,例如,與給定團隊比賽的先前比賽。)
我最初的想法是:
from django.db.models import Q, F, Count
matches = Match.objects.filter(team__name='xyz')
matches.annotate(
prior_matches=Count('match_id', filter=(
Q(start_time__lt=F('start_time')
))
)
不幸的是,這似乎為所有對象提供了prior_matches=0
。
這個問題建議遵循一個外鍵並使用反向關系,但這似乎很笨拙,而且還存在兩個問題:
Match
對象都用作外鍵,但這似乎並不理想。 matches.annotate(
prior_matches=Sum(Case(
When(start_time__lt=F('league__matches__start_time'), then=1),
default=0,
output_field=models.IntegerField()
))
)
matches
的queryset過濾特定的團隊。 我想不出一個好辦法(除了重復在每個Q
/ filter
子句中應用到queryset的完整過濾條件外,這在管理器中無法普遍使用)。 為了避免xy問題,為了在數據庫級別工作,我希望替換的(偽)代碼片段之一如下:
def generate_stats(match):
matches = Match.objects.filter(start_time__lt=match.start_time)
for team in (match.home_team, match.away_team):
q_involving = Q(home_team=team) | Q(away_team=team)
team_matches = matches.filter(q_involving)
team_matches.aggregate(...) # get stats
我認為您應該將第一個代碼更改為
from django.db import models
class Match(models.Model):
match_id = models.AutoField(primary_key=True)
start_time = models.DateTimeField()
league = models.ForeignKey(League, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete.models.CASCADE)
否則,可能是您尚未真正添加“匹配”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.