2015-12-16 3 views
1

Следующая строка создает список существующих точек данных:Возвращает список отсутствующих значений?

datapoint_list = organisation.datapoint_set.filter(timestamp__gte=startDate, timestamp__lte=endDate) 

Я хотел бы return в формате JSON даты от startDate до lastDate, для которых не существует ни одна из существующих DataPoint.

Как это можно сделать?

Моя лучшая идея заключается в следующем:

class Missing(generics.ListAPIView) 
    ... 
    queryset = organisation.datapoint_set.filter(timestamp__gte=startDate, timestamp__lte=endDate) 

    Loop over the datesdelta 
     Loop over the datapoints 
      If datapoint.timestamp == datedelta.timestamp then 
       Push timestamp to object 
       Continue 
      End if 
     End loop 
    End loop 
    Return object 

Но мне не удалось в сквозных датах. А может быть, есть еще более простой способ сделать это?

EDIT:

datesdelta определяются параметры запроса и должен взглядом по умолчанию для отсутствующих точек данных в последней неделе:

days = int(self.request.query_params.get('days', 7)) 
    startDate = datetime.today() - timedelta(days) 
    endDate = datetime.today() 

QuerySet содержит:

<DataPoint: Value: 123, Timestamp: 2015-12-15> 
<DataPoint: Value: 123, Timestamp: 2015-12-11> 
<DataPoint: Value: 123, Timestamp: 2015-12-10> 
<DataPoint: Value: 123, Timestamp: 2015-12-09> 
<DataPoint: Value: 123, Timestamp: 2015-12-08> 

Выход JSON должен выглядеть примерно так:

[ 
    'date': '2015-12-16', 
    'date': '2015-12-14', 
    'date': '2015-12-13', 
    'date': '2015-12-12', 
    'date': '2015-11-07' 
} 

Мой вопрос: как получить от этого набора запросов к этому выводу.

+0

Можете ли вы дать более подробную информацию пожалуйста, например, о содержании списка дат и о том, как он выглядит так, как вы хотите? – DhiaTN

+0

Спасибо за интерес к вопросу @DhiaTN! Я добавил дополнительные сведения в редактирование. – user1283776

ответ

2

set() Научитесь использовать это, и вы будете править миром !Во-первых, небольшое изменение в запросе, на примере вы показываете вы только хотите даты так что позволяет сделать запрос более эффективным:

queryset = organisation.datapoint_set.filter(timestamp__gte=startDate, timestamp__lte=endDate).values_list('timestamp', flat=True) 

сделано, то это будет выглядеть примерно так:

queryset = [datetime(2015,12,15), datetime(2015,12,11), datetime(2015,12,10), datetime(2015,12,9), datetime(2015,12,8)] 

Теперь мы формируем значения, которые мы хотим:

>>> set([endDate - timedelta(x) for x in xrange(days)]) 
set([datetime.date(2015, 12, 14), datetime.date(2015, 12, 16), datetime.date(2015, 12, 15), datetime.date(2015, 12, 12), datetime.date(2015, 12, 13), datetime.date(2015, 12, 10), datetime.date(2015, 12, 11)]) 

совершенен, и мы (вычесть их) -:

>>> set([endDate - timedelta(x) for x in xrange(days)]) - set(queryset) 
set([datetime.date(2015, 12, 14), datetime.date(2015, 12, 16), datetime.date(2015, 12, 15), datetime.date(2015, 12, 12), datetime.date(2015, 12, 13), datetime.date(2015, 12, 10), datetime.date(2015, 12, 11)]) 

позволяет сделать все это довольно:

import datetime 
days = 10 
# a bit of a hack to get the current date without any time stuff. 
endDate = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time()) 
queryset = [datetime.datetime(2015,12,15), datetime.datetime(2015,12,11), datetime.datetime(2015,12,10), datetime.datetime(2015,12,9), datetime.datetime(2015,12,8)] 
date_ranges = set([endDate - datetime.timedelta(x) for x in xrange(days)]) 
output = sorted(list(date_ranges - set(queryset))) 
print([x.strftime('%Y-%m-%d') for x in output]) 

выход:

['2015-12-07', '2015-12-12', '2015-12-13', '2015-12-14', '2015-12-16'] 

если вы Timestamps приходят как date объекты его еще проще:

import datetime 
days = 10 
endDate = datetime.date.today() 
queryset = [datetime.date(2015,12,15), datetime.date(2015,12,11), datetime.date(2015,12,10), datetime.date(2015,12,9), datetime.date(2015,12,8)] 
date_ranges = set([endDate - datetime.timedelta(x) for x in xrange(days)]) 
output = sorted(list(date_ranges - set(queryset))) 
print([x.strftime('%Y-%m-%d') for x in output]) 
1

можно сделать следующим образом:

class MissingListApiView(generics.ListAPIView) 
    model = Organisation 
    serializer_class = OrganisationSerializer 

    def get_queryset(self): 

     datapoint_list = organisation.datapoint_set.filter(timestamp__gte=today-timedelta(days), timestamp__lte=today) 
     get_timestap = lambda x: x.timestamp 
     timestamp_list = map(get_timestap, datapoint_list) 
     response = list() 
     push = response.append 
     for day in xrange(days+1): 
      date = datetime.today() + timedelta(days=-day) 
      if str(dat) not in timestamp_list: 
      push(datapoint.timestamp) 
     Return response 
2

Вы можете получить все временные метки из запроса с использованием values_list(). Для того, чтобы получить только определенные значения в результате вы можете объединить values_list с distinct()

timestamps = organisation.datapoint_set.filter(timestamp__gte=today-timedelta(days), timestamp__lte=today).values_list('timestamp',flat=True) 

Так что теперь timestamps список содержит все временные метки, на которых Eсть некоторые данные указывают. Вы можете захотеть o сначала преобразовать их в строковые объекты.

ts = [str(t) for t in timestamps] 

Теперь цикл по дням с today до today-days

ts_list = [] 
for day in xrange(days+1): 
    dat = datetime.today() + timedelta(days=-day) 
    if str(dat) not in ts: 
     print dat 
     ts_list.append(dat) 

Это даст все даты, которые не имеют точек данных

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