Как создать настраиваемую функцию поиска по фильтру в 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 )
Вернуться на верх