ORM Джанго. Группировать по элементам с разницей

У меня есть эта модель Джанго:

class Visits(models.Model):
    ip = models.GenericIPAddressField()
    url = models.CharField(max_length=200)
    datetime = models.DateTimeField(auto_now_add=True)

 def __unicode__(self):
    return "%s : %s (%s)" % (unicode(self.ip), 
                             unicode(self.datetime.strftime('%d/%m/%y %H:%M:%S')), 
                             unicode(self.url))

Он содержит все посещения моего веб-сайта. Например, это все значения из БД:

<Visits: 127.0.0.1 : 27/11/14 00:00:00 (/)>,
<Visits: 127.0.0.1 : 27/11/14 00:01:00 (/)>, 
<Visits: 127.0.0.1 : 27/11/14 00:09:00 (/)>, 
<Visits: 127.0.0.1 : 27/11/14 00:45:00 (/)>, 
<Visits: 127.0.0.1 : 27/11/14 00:46:00 (/)>

Я хочу написать запрос ORM, который группирует значения с 15-минутной дельтой. Например, этот запрос должен вернуть count()==2 (первые три значения находятся в первой группе, вторые два — во второй). Как я могу сделать это с помощью Django ORM?


person michaeluskov    schedule 27.11.2014    source источник
comment
это не просто сделать, вы должны сначала разработать правильный SQL для его достижения, а затем вернуться к Django ORM. вам, вероятно, придется использовать метод extra, возможно, будет возможен собственный класс агрегации, иначе просто метод raw   -  person Anentropic    schedule 27.11.2014
comment
см. этот аналогичный вопрос stackoverflow.com/q/9950573/202168   -  person Anentropic    schedule 27.11.2014
comment
Под 15-минутной дельтой вы подразумеваете объекты, имеющие объект datetime, равный и превышающий 15 минут, верно?   -  person Tanveer Alam    schedule 27.11.2014
comment
Я предполагаю, что вам сначала нужно аннотировать набор запросов со значением, подобным метке времени, которое представляет каждое конкретное 15-минутное окно, а затем агрегировать по какому-то другому полю, но сгруппировать по полю аннотации. это может помочь docs. djangoproject.com/en/dev/topics/db/aggregation/   -  person Anentropic    schedule 27.11.2014
comment
@michaeluskov Если вам нужен результат, основанный на разных IP-адресах, то почему вы ожидаете count () == 2 в течение 15 или более минут в случае уникального IP-адреса 127.0.0.1?   -  person Tanveer Alam    schedule 27.11.2014


Ответы (1)


введите здесь описание изображения

Здесь у меня четыре визита, и я попытался отфильтровать их по мелочам, превышающим 28.

>>> visits_count = len([ obj for obj in Visits.objects.all() if obj.datetime.strftime('%M') >  '28'])
>>> visits_count
2

Это для случаев, когда число меньше, чем равно 28.

>>> visits_count = len([ obj for obj in Visits.objects.all() if obj.datetime.strftime('%M') >=  '28'])
>>> visits_count
4
person Tanveer Alam    schedule 27.11.2014
comment
Первый ответ должен быть 3 (первый, второй и два последних) - person michaeluskov; 27.11.2014
comment
Если вы хотите, чтобы он отличался по ip, вы можете использовать запрос для объекта в Visits.objects.distinct('ip') - person Tanveer Alam; 27.11.2014
comment
Если вам нужен результат, основанный на разных IP-адресах, то почему вы ожидаете count()==2 в течение 15 минут или более в случае уникального IP-адреса 127.0.0.1? - person Tanveer Alam; 27.11.2014
comment
@Downvoter, пожалуйста, укажите причину вашего отрицательного голоса? - person Tanveer Alam; 27.11.2014