简体   繁体   English

如何根据外键字段对查询集进行排序?

[英]How to sort a queryset based on a foreign key field?

This is a contest system project.这是一个竞赛系统项目。 I have these models and I know the contest_id and problem_id.我有这些模型,我知道 contest_id 和 problem_id。 I'm trying to return a queryset that contains users who have solved a problem.我正在尝试返回一个包含已解决问题的用户的查询集。 A user who solves a problem is the one whose submission's score is equal to score of the problem he tried to solve.解决问题的用户提交的分数等于他试图解决的问题的分数。 At the end I need to sort these users based on the time they have submitted their successful submission.最后我需要根据他们提交成功的时间对这些用户进行排序。

class Contest(models.Model):
   name = models.CharField(max_length=50)
   holder = models.ForeignKey(User, on_delete=models.CASCADE)
   start_time = models.DateTimeField()
   finish_time = models.DateTimeField()
   is_monetary = models.BooleanField(default=False)
   price = models.PositiveIntegerField(default=0)
   problems = models.ManyToManyField(Problem)
   authors = models.ManyToManyField(User, related_name='authors')
   participants = models.ManyToManyField(User, related_name='participants')

class Problem(models.Model):
   name = models.CharField(max_length=50)
   description = models.CharField(max_length=1000)
   writer = models.ForeignKey("accounts.User", on_delete=models.CASCADE)  
   score = models.PositiveIntegerField(default=100)

class Submission(models.Model):
   submitted_time = models.DateTimeField()
   participant = models.ForeignKey(User, related_name="submissions", on_delete=models.CASCADE)
   problem = models.ForeignKey(Problem, related_name="submissions", on_delete=models.CASCADE)
   code = models.URLField(max_length=200)
   score = models.PositiveIntegerField(default=0)

I tried following code but I get wrong answer.我尝试了以下代码,但得到了错误的答案。 How can I sort my QuerySet?如何对我的 QuerySet 进行排序?

def list_users_solved_problem(contest_id, problem_id):
    problem_score = Problem.objects.get(id=problem_id).score

    successful_submissions_ids = Submission.objects.filter(
    Q(score=problem_score) & Q(problem__id=problem_id)).
    values_list('participant__id', flat=True)

    return Contest.objects.get(id=contest_id).
    participants.filter(id__in=successful_submissions_ids).
    order_by('submissions__submitted_time')


You can .filter(…) [Django-doc] with:你可以.filter(…) [Django-doc]

from django.db.models import F

User.objects.filter(
    participants=contest_id, submissions__problem_id=problem_id, submissions__score=F('submissions__problem__score')
).order_by('submissions__submitted_time')

The modeling looks however "strange": the submission is not linked to the contest.然而,建模看起来很“奇怪”:提交的内容与比赛没有关联。 So if two (or more) contests share the same problem, then that means it will take the first complete submission to that problem, regardless what the contest is.因此,如果两个(或更多)比赛共享同一个问题,那么这意味着它将首先完整提交该问题,无论比赛是什么。


Note : It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly.注意:通常使用settings.AUTH_USER_MODEL [Django-doc]来引用用户 model 比直接使用User模型[Django-doc]更好。 For more information you can see the referencing the User model section of the documentation .有关详细信息,您可以参阅文档中引用User model的部分

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM