джанго, ограничь дженерики.Список просмотров по неделям введенного пользователем поля filterset_

#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