Как отсортировать набор запросов на основе поля внешнего ключа?

Это проект конкурсной системы. У меня есть эти модели и я знаю contest_id и problem_id. Я пытаюсь вернуть набор запросов, который содержит пользователей, решивших проблему. Пользователь, решивший проблему, - это тот, чей балл заявки равен баллу проблемы, которую он пытался решить. В конце мне нужно отсортировать этих пользователей на основе времени, когда они подали свою успешную заявку.

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')so

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)

Я пробовал следующий код, но не получаю неправильного ответа. Как я могу отсортировать мой 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.order_by('submissions__submitted_time')

Вы можете .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')

Однако моделирование выглядит "странно": представление не связано с конкурсом. Поэтому если два (или более) конкурса имеют одну и ту же проблему, то это означает, что будет принята первая полная подача на эту проблему, независимо от того, какой это конкурс.


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. For more information you can see the referencing the User model section of the documentation.

Вернуться на верх