Как создать настраиваемую функцию поиска по фильтру в Django?
Я пытаюсь создать строку поиска фильтра, которую можно настроить. Например, если я введу значение в строку поиска, то она запросит модель и получит список экземпляров, которые соответствуют этому значению. Например, вот представление:
class StudentListView(FilterView):
template_name = "leads/student_list.html"
context_object_name = "leads"
filterset_class = StudentFilter
def get_queryset(self):
return Lead.objects.all()
и вот мой filters.py: class
StudentFilter(django_filters.FilterSet):
class Meta:
model = Lead
fields = {
'first_name': ['icontains'],
'email': ['exact'],
}
До сих пор я могу создать только строку поиска фильтра, которая может предоставить список экземпляров, соответствующих first_name
или email
(которые являются полями в модели Lead
). Однако теперь это позволяет мне выполнять более сложные задачи. Допустим, я добавил time
к полям фильтра, и я хотел бы не только фильтровать модель Lead
со значением time
, которое я представил, но и другие экземпляры Lead
, которые имеют значение time
, близкое к тому, которое я представил. В принципе, я хочу что-то вроде def form_valid()
, используемое в представлениях, где я могу запрашивать, вычислять и даже изменять представленные значения.
Более того, если возможно, я хотел бы создать поле фильтра, которое не обязательно является фактическим полем в модели. Затем я хотел бы использовать представленное значение для выполнения некоторых вычислений в процессе фильтрации списка экземпляров. Если у вас есть какие-либо вопросы, пожалуйста, задавайте их в комментариях. Спасибо.
Вы можете сделать практически все, что угодно, определив метод на filterset для отображения пользовательского ввода на queryset. Вот один из них, который я сделал ранее. Код значительно сокращен ...
Фильтр coat_info_contains
определяется как CharFilter
, но далее разбирается методом, который разбивает его на набор подстрок, разделенных запятыми. Эти подстроки затем используются для генерации элементов Q
(логика OR) для соответствия модели, если подстрока содержится в любом из трех полей модели coating_1
, coating_2
и coating_3
Этот фильтр неявно не связан с каким-либо конкретным полем модели. Связь осуществляется через method=
спецификацию фильтра к методу filterset, который может вернуть абсолютно любой кверисет на модели, который может быть запрограммирован.
Надеюсь, я не вырезал ничего жизненно важного.
import django_filters as FD
class MemFilter( FD.FilterSet):
class Meta:
model = MyModel
# fields = [fieldname, ... ] # default filters created for these. Not required if all declarative.
# fields = { fieldname: [lookup_expr_1, ...], ...} # for specifying possibly multiple lookup expressions
fields = {
'ft':['gte','lte','exact'], 'mt':['gte','lte','exact'],
...
}
# declarative filters. Lots and lots of
...
coat_info_contains = FD.CharFilter( field_name='coating_1',
label='Coatings contain',
method='filter_coatings_contains'
)
...
def filter_coatings_contains( self, qs, name, value):
values = value.split(',')
qlist = []
for v in values:
qlist.append(
Q(coating_1__icontains = v) |
Q(coating_2__icontains = v) |
Q(coating_3__icontains = v) )
return qs.filter( *qlist )