#python #django-views #django-pagination
Вопрос:
Новичок в django и начинающий с api. Я хотел бы, чтобы мое представление принимало поле набора фильтров, а затем возвращало данные в течение одной недели, превышающие это поле. Представление, которое я настроил в настоящее время, является
views.py
class MeterView(generics.ListAPIView):
queryset = MeterLake.objects.all()
serializer_class = MeterLakeSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields = {'siteid' : ['exact'],
'createdtimestamp' : ['gte'],
}
затем пользователь вводит URL/?createdtimestamp=дата
Затем я хотел бы взять введенную пользователем дату и вернуть информацию, превышающую одну неделю с этой даты.
В идеале я хотел бы использовать для этого разбиение на страницы, но я не уверен, что буду очень признателен за любую помощь!
Ответ №1:
Вы можете настроить способ использования поля фильтра метки времени, предоставив пользовательский класс filterset_class, который будет использоваться вместо сокращенного способа, используемого в настоящее время.
Например, указав метод для фильтра, вы можете настроить значение, используемое для поиска.
from django_filters import rest_framework as filters
from datetime import datetime, timedelta
class MeterLakeFilter(filters.FilterSet):
createdtimestamp = filters.BooleanFilter(
field_name='createdtimestamp', method='filter_a_week_from_date'
)
class Meta:
model = MeterLake
fields = ['createdtimestamp', 'siteid']
def filter_a_week_from_date(self, queryset, name, value):
lookup = f'{name}__gte'
dateformat = '%Y-%m-%d' # replace with expected value format.
# value may be serialized already, thus not needing to be parsed here.
value = datetime.strptime(value, dateformat) timedelta(days=7)
return queryset.filter(**{lookup: value})
class MeterView(generics.ListAPIView):
queryset = MeterLake.objects.all()
serializer_class = MeterLakeSerializer
filter_backends = [DjangoFilterBackend]
filterset_class = MeterLakeFilter
Комментарии:
1. Спасибо! Это отлично работает при фильтрации по идентификатору сайта, но он борется с фильтром по дате. Я думаю, что проблема, вероятно, связана с моим значением даты и времени. Каков наилучший способ проверить, какова эта ценность? Обычно я бы распечатал его, но у меня возникли проблемы с доступом к переменной.
Ответ №2:
Используя ответ Олувафеми Суле, я смог настроить пользовательский фильтр и общий вид для поиска по идентификатору сайта и через неделю после введенной отметки времени. Я также добавил некоторые функции, чтобы ограничить диапазон времени одной неделей с сегодняшнего дня, если метка времени не указана.
class MeterLakeFilter(filters.FilterSet):
siteid = filters.CharFilter(field_name='siteid')
createdtimestamp = DateTimeFilter(field_name = 'createdtimestamp', method = 'filter_a_week_from_date')
class Meta:
model = MeterLake
fields = ['siteid', 'createdtimestamp']
def filter_a_week_from_date(self,queryset, name, value):
if self.request.query_params.get('createdtimestamp', 'None') == None:
lookup = f'{name}__gte'
value = datetime.now() timedelta(days=7)
return queryset.filter(**{lookup: value})
else:
value2 = value timedelta(days=7)
return queryset.filter(createdtimestamp__lte = value2, createdtimestamp__gte = value)
class MeterView(generics.ListAPIView):
queryset = MeterLake.objects.all()
serializer_class = MeterLakeSerializer
filter_backends = [DjangoFilterBackend,OrderingFilter]
filterset_class = MeterLakeFilter
ordering_fields = ['siteid', 'createdtimestamp']
ordering = ['siteid', 'createdtimestamp']
def get_queryset(self):
if self.request.query_params.get('createdtimestamp', None) == None:
start_date = datetime.utcnow().replace(tzinfo=pytz.utc)
end_date = start_date - timedelta(days=7)
queryset = MeterLake.objects.filter(createdtimestamp__gte = end_date).order_by('createdtimestamp')
return queryset
else:
pass