我有以下型号:
class Contest(models.Model):
id_contest = models.AutoField(primary_key=True)
name = models.CharField(max_length=50, blank=False)
class Registration(models.Model):
id_registration = models.AutoField(primary_key=True)
team = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.DO_NOTHING,
related_name='registrations',
related_query_name='registration')
contest = models.ForeignKey(
Contest,
on_delete=models.DO_NOTHING,
related_name='registrations',
related_query_name='registration')
created_at = models.DateTimeField(null=True)
confirmed_at = models.DateTimeField(null=True)
class Submission(models.Model):
id_submission = models.AutoField(primary_key=True)
team = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.DO_NOTHING,
related_name='submissions',
related_query_name='submission')
contest = models.ForeignKey(
Contest,
on_delete=models.DO_NOTHING,
related_name='submissions',
related_query_name='submission')
submitted_at = models.DateTimeField(null=True)
is_valid = models.NullBooleanField()
public_score = models.FloatField(null=True)
我正在处理排行榜查询(PostgreSQL),如:
select
r.team_id,
max(t.username) as team_name,
count(s.team_id) as num_submissions,
min(s.public_score) as score,
max(s.submitted_at) as last_submission,
max(r.confirmed_at) as confirmation
from api_registration r
left join auth_user t on (r.team_id = t.id)
left join api_submission s on (r.contest_id = s.contest_id and s.team_id = t.id and s.is_valid = TRUE)
where r.contest_id = 1
group by r.team_id
order by score ASC, last_submission DESC;
返回我想要的结果。 但是,在转换为Django QuerySet操作时,最接近的是我 来的是:
leaderboard = Registration.objects \
.filter(contest=contest, contest__submission__is_valid=True) \
.annotate(team_name=Max('team__username'),
num_submissions=Count('team__submission'),
score=Min('contest__submission__public_score'),
last_submission=Max('contest__submission__submitted_at'),
confirmation=Max('confirmed_at')) \
.order_by('score', '-last_submission')
生成查询:
SELECT
"api_registration"."id_registration",
"api_registration"."team_id",
"api_registration"."contest_id",
"api_registration"."created_at",
"api_registration"."confirmed_at",
MAX("api_registration"."confirmed_at") AS "confirmation",
MAX("api_submission"."submitted_at") AS "last_submission",
MAX("auth_user"."username") AS "team_name",
MAX("api_submission"."public_score") AS "score",
COUNT(T5."id_submission") AS "num_submissions"
FROM "api_registration" INNER JOIN "api_contest" ON ("api_registration"."contest_id" = "api_contest"."id_contest")
INNER JOIN "api_submission" ON ("api_contest"."id_contest" = "api_submission"."contest_id")
INNER JOIN "auth_user" ON ("api_registration"."team_id" = "auth_user"."id")
LEFT OUTER JOIN "api_submission" T5 ON ("auth_user"."id" = T5."team_id")
WHERE ("api_registration"."contest_id" = 1
AND "api_submission"."is_valid" = True)
GROUP BY "api_registration"."id_registration"
ORDER BY "score" ASC, "last_submission" DESC;
并且没有正确计算每个团队提交的正确数量。 有关如何定义Django QuerySet操作以获得正确结果的任何帮助吗?
答案 0 :(得分:0)
尝试更改此内容:num_submissions=Count('team__submission'),
num_submissions=Count('team_id'),
。
这是根据表注册的team_id进行分组。