Пользовательская фильтрация в 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).