Пользовательская фильтрация в django rest framework

Я пытаюсь реализовать пользовательскую фильтрацию в своем коде и просмотрел документацию. Но я не смог понять следующие фрагменты из документации.

class UserFilter(django_filters.FilterSet):
    class Meta:
        model = User
        fields = ['username', 'last_login']

# or

class UserFilter(django_filters.FilterSet):
    class Meta:
        model = User
        fields = {
            'username': ['exact', 'contains'],
            'last_login': ['exact', 'year__gt'],
        }

В документе говорится, что мы можем использовать либо первый, либо второй вариант, но в чем точная разница? Каково значение contains и year_gt?

В документации есть ссылка на документацию django lookups docs, и вы обнаружите, что поиск/фильтрация могут быть более эффективными, если использовать второй вариант.

Первый вариант в документации, где fields - это просто список, будет выполнять запрос точного соответствия по каждому из перечисленных вами полей.

Во втором варианте библиотека фильтров будет работать со словарем fields, используя нотацию "двойного подчеркивания" для создания поиска по;

  • username__exact
  • username__contains
  • last_login__exact
  • last_login__year__gt

Вы можете использовать двойное подчеркивание для доступа к атрибуту чего-либо или к типу поиска. Поэтому в последнем примере last_login будет взят год значения last_login, а для этого года тип поиска будет больше, чем (gt).

Существует множество таких значений поиска, которые могут быть очень полезны для изучения. Например, contains чувствительно к регистру, но вы можете использовать icontains для нечувствительного к регистру соответствия. Есть также lt для значения меньше чем, или lte/gte для значения меньше/больше чем или равно. Просмотрите доступные варианты поиска здесь.

В чем именно разница?

При fields = ['username', 'last_login'] генерируемые фильтры :

qs.filter(username='some_value') и qs.filter(last_login=some_date_value)

With

fields = {
        'username': ['exact', 'contains'],
        'last_login': ['exact', 'year__gt'],
    }

генерируемые фильтры:

qs.filter(username='some_value'), qs.filter(username__contains='some_value') для поля username.

qs.filter(last_login=some_date_value), qs.filter(last_login__year__gt=some_year_value) для поля last_login.

Так мы видим, что в первом случае создается 2 варианта фильтра для каждого поля, а в первом - только один вариант фильтра (exact match) для заданного значения.

Какое значение содержит и год__gt?

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

С другой стороны,

year__gt предназначен только для поля даты. Когда у вас есть поле даты, например created, Django позволяет вам фильтровать по year, month, day, просто сделав : .filter(created__year=2021, created__month=12). И еще больше возможностей по .filter(created__year__gt=2020), что означает год создания поля > 2020. Это может быть применено к month__gt (месяц > 11), day__lt (день < 25).

Вернуться на верх