Запрос Django выбирается по парам полей - PullRequest
8 голосов
/ 14 августа 2010

У меня есть поле 'подчинение', в котором есть пользователь и проблема. Как я могу получить результат поиска SQL, который выдаст список только одного результата на пару пользователь-проблема?

Модели такие:

class Problem(models.Model):
    title = models.CharField('Title', max_length = 100)
    question = models.TextField('Question')

class Submission(models.Model):
    user = models.ForeignKey(User)
    problem = models.ForeignKey(Problem)
    solution = models.CharKey()
    time = models.DateTimeField('Time', auto_now_add=True)

Ответы [ 2 ]

13 голосов
/ 14 августа 2010

Попробуйте это:

distinct_users_problems = Submission.objects.all().values("user", "problem").distinct()

Это даст вам список таких диктовок:

[{'problem': 1, 'user': 1}, {'problem': 2, 'user': 1}, {'problem': 3, 'user': 1}]

содержит все различные пары.

На самом деле это приводит к обычному SQL-запросу SELECT DISTINCT.

3 голосов
/ 14 августа 2010

Обновление 2 :

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

class LatestSubmission(models.Model):
    user = models.ForeignKey(User)     
    problem = models.ForeignKey(Problem)
    submission = models.ForeignKey(Submission)

Вы можете затем либо

  1. переопределить Submission.save() для создания / обновления записи в LatestSubmission каждый раз, когда пользователь публикует новое решение для проблемы
  2. присоединяет функцию, которая делает то же самое, к подходящему сигналу .

, так что LatestSubmission будет содержать по одной строке для каждой комбинации проблема-пользователь-отправка, указывающей на последнюю отправку для проблемы каждым пользователем. Если у вас есть это, вы можете запустить один запрос:

LatestSubmission.objects.all().order_by('problem')

Обновление :

Поскольку OP опубликовал пример кода, решение теперь можно изменить следующим образом:

for user in User.objects.all(): # Get all users
    user.submission_set.latest('time') # Pick the latest submission based on time.

Оригинальный ответ

В отсутствие каких-либо критериев, основанных на дате / времени, для принятия решения, какой из них «старше» или «новее», вы можете использовать первичный ключ (id) Submission, чтобы «пренебречь старыми».

for user in User.objects.all(): # Get all users
    user.submission_set.latest('id') # Pick the latest submission by each user.
...