Фильтрация поля диапазона дат с диапазоном дат

#python #django

Вопрос:

Приложение React / Django. Я хочу добавить фильтр диапазона дат (flatpickr) к уже существующим фильтрам для заказов. period В Orders есть поле (как долго действует заказ), которое является DateRange полем. С помощью flatpickr я выбираю диапазон дат, и если хотя бы один день периода заказа находится в этом выбранном диапазоне дат, он должен отображаться в результате.

например. период: DateRange(datetime.date(2021, 2, 11), datetime.date(2021, 3, 14), '[)')

У меня есть готовый фильтр в FE для приема результатов из BE. Но я не уверен, как добиться этого в BE. Поскольку я довольно новичок в этом, мои идеи ограничены, но в настоящее время у меня есть это:

 ...
from django_filters.rest_framework import DjangoFilterBackend, IsoDateTimeFilter, FilterSet
from rest_framework import filters, mixins, status
...

class OrderFilter(FilterSet):

    start_date = IsoDateTimeFilter(field_name="period", lookup_expr="gte")
    end_date = IsoDateTimeFilter(field_name="period", lookup_expr="lte")

    class Meta:
        model = Order
        fields = {
            "status": ["in"],
            "client": ["exact"],
            "created_by": ["exact"],
        }

        ordering_fields = ["period", "client__name", "destination__name"]
        ordering = ["period"]
        custom_field_target_model = Order
 

Я считаю, что самое близкое, что я нашел, это IsoDateTimeFromToRangeFilter, но, похоже, это не то, что я ищу.

Ответ №1:

Поскольку ваше поле является DateRangeField , ваши выражения поиска ограничены. Вы можете использовать следующие параметры:

  1. содержит
  2. contained_by
  3. перекрытие

Если ваш случай, чтобы определить, содержит ли период определенный диапазон дат (start_date, end_date), вы можете использовать его как:

 Order.objects.filter(period__contains=(start_date, end_date))
 

вы также можете играть с другими, если хотите.

Проблема здесь не в классе фильтра, а в поле, которое вы пытаетесь отфильтровать. Если вы сохраняете period_start_date и period_end_date отдельно, вы можете фильтровать даты отдельно. Чтобы отфильтровать поле с двумя входами, вы можете использовать пользовательский метод фильтра или переопределить get_queryset метод вашего представления.

Нет: как упоминал @aberkb, вам нужно добавить «период» в поля.

Комментарии:

1. Я делаю запрос от FE с помощью react через API, используя диапазон дат с двумя датами start_date и end_date. Итак, у меня нет start_date и end_date, фактически доступных в BE. Что касается вашего первого предложения по использованию DateFromToRangeFilter , я не понимаю, как бы я использовал его в моем случае: отфильтровывать заказы, срок действия которых составляет не менее 1 дня, перекрываясь с диапазоном дат фильтра. Не могли бы вы, пожалуйста, подробнее остановиться на этом, или не могли бы вы привести более широкий пример?

2.В идеале я ищу что-то вроде этого: start_date = DateFromToRangeFilter(field_name="period__lower", lookup_expr="gte") end_date = DateFromToRangeFilter(field_name="period__upper", lookup_expr="lte") есть ли способ заставить что-то подобное работать?

3. @perrer Я обновил свой ответ, вы можете найти полезную информацию, чтобы определить путь решения вашей проблемы.