2014-09-27 2 views
0

У меня возникли трудности с «агрегатом» и «последним».Django - «Найти последние» детей для всех строк

У меня есть эти две модели:

class Word(models.Model): 
    ESSENTIALWORDS = 'EW' 
    FOOB = 'ER' 
    OTHER = 'OT' 
    WORDSOURCE_TYPE_CHOICES = (
     (ESSENTIALWORDS, 'Essential Words'), 
     (FOOB, 'FOOB'), 
     (OTHER, 'OTHER'), 
    ) 

    level = models.IntegerField() 
    word = models.CharField(max_length=30) 
    source = models.CharField(max_length=2, 
           choices=WORDSOURCE_TYPE_CHOICES, 
           default=OTHER) 
    hint = models.CharField(max_length=30, null=True, blank=True) 


class Attempt(models.Model): 
    learner = models.ForeignKey(Learner) 
    word = models.ForeignKey(Word) 
    when = models.DateTimeField(auto_now_add=True) 
    success = models.BooleanField(default=False) 

Я хочу, чтобы найти все Word объекты, для которых самый последний Attempt (на основе поля when) имеет success значение True.

ответ

1

Это должно работать:

from django.db.models import Max, F 

Word.objects.annotate(latest=Max('attempt__when')) 
      .filter(attempt__success=True, 
        attempt__when=F('latest')) 

Во-первых, каждый Word является annotated с датой самого последнего (то есть Max) попытки. Затем объекты Word фильтруются, чтобы включать только те, которые имеют соответствие Attempt, где success - True и где дата соответствует последней дате. (F используется для представления значения другого столбца или в данном случае аннотации.)

+0

Спасибо, Кевин. Мне жаль, что я так долго признался, но на самом деле мне потребовалось немного времени, чтобы решить, действительно ли ответ был правильным! Моя следующая задача - лучше понять * почему * это работает ;-). Еще раз спасибо. – glaucon

+0

@glaucon: Добро пожаловать. Я добавил объяснение, надеюсь, сделать это более ясным. Если вы следуете ссылкам и читаете об аннотации и объектах F, я думаю, что это будет иметь смысл. –

Смежные вопросы