2015-04-19 2 views
1

У меня есть следующая модель и вы хотите сделать запрос фильтра на это.Получить последние по полю для списка пользователей

class Invite(models.Model): 
    user  = models.ForeignKey(User, related_name='user_invite') 
    template = models.CharField(max_length=500, null=True, blank=True) 
    user_time = models.TimeField(blank=True, null=True) 
    user_date = models.DateField(blank=True, null=True) 

Мне нужно отфильтровать список приглашений для данного списка пользователей, для которых данный шаблон является последним шаблоном.

Например:

| id | user_id | template | user_time | user_date | 
| -- | --------| -------- | --------- | ----------- | 
| 5 | 3  | temp-A | 03:40PM | 19/04/2015 | 
| 4 | 1  | temp-B | 03:40PM | 19/04/2015 | 
| 3 | 2  | temp-A | 03:40PM | 19/04/2015 | 
| 2 | 2  | temp-B | 01:30PM | 17/04/2015 | 
| 1 | 1  | temp-A | 01:30PM | 17/04/2015 | 

Здесь для user_id 1, недавний шаблон temp-B на основе user_date и user_time и user_id 2 и 3, это temp-A. Здесь, если данный список пользователей равен [1,2,3], а данный шаблон - temp-A, список результатов ID должен быть [2,3].

Если я делаю запрос

Invite.objects.filter(user_id__in = user_id_list, template = 'temp-A').values_list('user_id', flat = True) 

результат будет [1,2,3], как все пользователи получили шаблон temp-A. Но я хочу фильтровать пользователей, для которых данный шаблон является последним. Как достичь этого с помощью запросов фильтра django без использования каких-либо циклов?

ответ

0

Вы столкнулись с проблемой greatest-n-per-group. В Django он не может быть разрешен с помощью одного запроса, но с двумя. Следующее, что я собираюсь опубликовать, - это не совсем то, что вы хотите, но очень близко к нему - возвращает самые последние приглашения для каждого пользователя на максимальный приглашение id (не на дату, как вы хотели). Если вы не можете его использовать, я надеюсь, что он, по крайней мере, даст вам несколько направлений для будущих. Я также попытаюсь найти лучшее решение.

invites = Invite.objects.filter(
    id__in=User.objects.filter(
      id__in=[1,2,3], 
      user_invite__template='temp-A' 
     ).annotate(
      max_invite_id=Max('user_invite__id') 
     ).values_list('max_invite_id', flat=True) 
) 
Смежные вопросы