2017-01-10 1 views
0

У меня есть 2 модели: Subscriber и Notification.Django выбрать и заказать на основе соответствующей стоимости

class Subscriber(models.Model): 
    email = models.CharField() 

class Notification(models.Model): 
    subscriber = models.ForeignKey(Subscriber, related_name='notifications') 
    timestamp = models.DateTimeField(default=timezone.now) 
    type = models.SmallIntegerField(choices=TYPES) 

То, что я хочу, чтобы получить это абоненты, которые не получили уведомление (на основе type) в течение последних 5 минут и заказать их по времени, когда они в последний раз получили по возрастанию.

Я бы, вероятно, решил это в sql с подзапросом или что-то в этом роде, но мне интересно, можно ли это сделать в Django.

Вот рабочий SQL-запрос, который делает то, что мне нужно:

SELECT 
    s.* 
FROM 
    subscribers s 
    LEFT JOIN 
     notifications n 
     ON(n.subscriber_id = s.id) 
WHERE 
    (
(NOT EXISTS 
     (
      SELECT 
       NULL 
      FROM 
       notifications nn 
      WHERE 
       nn.subscriber_id = s.id 
     ) 
     OR 
     (
      n.type = 1 
      AND n.timestamp < Curdate() - INTERVAL 5 minute 
     ) 
) 
    ) 
ORDER BY 
    pu.timestamp ASC 

ответ

0

Вы можете использовать метод exclude QuerySet исключить абонентов, которые имеют получили уведомление, а затем аннотировать QuerySet с последним полученным уведомлением в отдайте приказ.

from datetime import timedelta 
from django.db.models import Max 

five_minutes_ago = timezone.now() - timedelta(minutes=5) 
Subscriber.objects.exclude(
    notifications__type='notification_type_x', 
    notifications__time__gt=five_minutes_ago 
    ) 
    .annotate(last_notification=Max('notifications__time')) 
    .order_by('last_notification')