Django: Получить кастомный объект если не найдено ничего
Мне нужно построить статистику сессий пользователя. Проблема возникает что присутствуют моменты когда в периоде времени нет данных. и их надо отобразить дефолтными значениями. получаю ответ:
[
{
"time": "2021-06-14T11:57:00",
"ip": "255.253.250.255",
"count": 3
},
{
"time": "2021-06-14T12:02:00",
"ip": "255.253.250.255",
"count": 3
},
{
"time": "2021-06-14T12:12:00",
"ip": "255.253.250.255",
"count": 3
},
{
"time": "2021-06-14T12:17:00",
"ip": "255.253.250.255",
"count": 3
}
]
а нужно:
[
{
"time": "2021-06-14T11:57:00",
"ip": "255.253.250.255",
"count": 3
},
{
"time": "2021-06-14T12:02:00",
"ip": "255.253.250.255",
"count": 3
},
{
"time": "2021-06-14T12:07:00",
"ip": 0,
"count": 0
},
{
"time": "2021-06-14T12:12:00",
"ip": "255.253.250.255",
"count": 3
},
{
"time": "2021-06-14T12:17:00",
"ip": "255.253.250.255",
"count": 3
}
]
имеется такой код:
class SessionModel(models.Model):
class Meta:
db_table = 'statistic'
time = models.DateTimeField()
name = models.CharField(max_length=16)
source = models.GenericIPAddressField()
ip = models.GenericIPAddressField()
token = models.CharField(max_length=255, blank=True)
user_id = models.CharField(max_length=255, blank=True)
count = models.IntegerField(blank=True)
def save(self, *args, **kwargs):
self.time = timezone.now().replace(second=0, microsecond=0).isoformat(' ')
return super(SessionModel, self).save(*args, **kwargs)
class TokenStatView(APIView):
serializer_class = SessionSerializer
permission_classes = [AllowAny]
def get(self, request, *args, **kwargs):
base = datetime.datetime.today()
date_list = [(base - datetime.timedelta(minutes=5) * x).strftime('%Y-%m-%d %H:%M') for x in range(24 * 12)]
token_or_ip = kwargs.get('pk')
if token_or_ip.count('.') == 3 and all(0 <= int(num) < 256 for num in token_or_ip.rstrip().split('.')):
result = SessionModel.objects.filter(ip=token_or_ip, time__in=date_list).values('time',
'ip').annotate(
count=Sum('count')).order_by('ip', 'time')
else:
result = SessionModel.objects.filter(token=token_or_ip, time__in=date_list).values('time',
'ip').annotate(
count=Sum('count')).order_by('ip', 'time')
return Response(result, status.HTTP_200_OK)
Ответы (1 шт):
Автор решения: Za Ars
→ Ссылка
Переопределите get_queryset. преобразуйте его в список и вставьте нужные значения в нужные места. можете сформировать новый список (так проще будет).
Судя по примеру, интервал должен быть в 5 минут. можете сами отсчитывать время, либо от прошлого добавленного в список, объекта
Также, можете написать фильтр, если используете django-filters, чтобы не засорять view.