Фильтры Django: Предложите улучшения в логике динамической фильтрации - PullRequest
0 голосов
/ 20 октября 2018

Я выполняю фильтрацию по моему набору данных на основе множества критериев поиска, выбранных пользователями во внешнем интерфейсе.Вот несколько соображений:

  • Все критерии фильтра не являются обязательными.Пользователь может выбрать / ввести значения или оставить это поле пустым.Бэкэнд должен найти способ проверки NULL.
  • Раскрывающиеся списки являются множественными, поэтому данные формы фильтра могут иметь несколько списков идентификаторов.(много запросов IN)
  • Есть также поля, связанные с датой (от / до), которые можно оставить пустыми.Таким образом, код должен обрабатывать следующие сценарии: Фильтрация диапазона дат |Дата> ДДММГГГГ |Дата <ДДММГГГ. </li>

Вот как выглядит форма: my form

Это мой текущий подход:

class BookingExportFilterBackend(generic_filters.BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        predicate = request.data

        if all(dt in predicate for dt in ('from_date', 'to_date')):
            queryset = queryset.filter(date__range=(predicate['from_date'], predicate['to_date']))

        if 'from_date' in predicate and 'to_date' not in predicate:
            queryset = queryset.filter(date__gte=predicate['from_date'])

        if 'to_date' in predicate and 'from_date' not in predicate:
            queryset = queryset.filter(date__lte=predicate['to_date'])

        if 'state' in predicate:
            queryset = queryset.filter(state__in=predicate['state'])

        if 'clients' in predicate:
            queryset = queryset.filter(client__in=predicate['clients'])

        if 'camera_operators' in predicate:
            queryset = queryset.filter(camera_operator__uuid__in=predicate['camera_operators'])

        return queryset

Я чувствую, что это может быть улучшено, особенно часть даты.Я также использую библиотеку Q, но я довольно новичок в Django.(PS: я пришел из Java / Spring / Hibernate фон.)

Пожалуйста, помогите улучшить код.

1 Ответ

0 голосов
/ 24 октября 2018

Вам следует попробовать django-filters lib для фильтрации.Он довольно прост в использовании и предоставляет ряд параметров фильтрации.

Для вашего случая вы можете начать с чего-то вроде этого: Примечание: пожалуйста, не используйте дату в качестве имени поля / переменной, я заменил наbooking_date в приведенном ниже примере.

class BookingFilter(django_filters.FilterSet):
    from_date = django_filters.NumberFilter(field_name='booking_date', lookup_expr='gt')
    to_date = django_filters.NumberFilter(field_name='booking_date', lookup_expr='lt')

    status = django_filters.CharFilter(name="status", lookup_type="contains"

    class Meta:
        model = Booking # replace with your appropriate Model
...