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

Моя функция просмотра выглядит следующим образом:

def search(request):

    queryset_list = Influencer.objects.order_by('-followers').distinct().values('id',
                                                                'full_name','username','photo','email_id','location_city','categories__name','website')

    # Username
    if 'username' in request.GET:
        username = request.GET['username']
        if username:
            queryset_list = queryset_list.filter(username__icontains=username)

    #Full Name
    if 'fullname' in request.GET:
        fullname = request.GET['fullname']
        if fullname:
            queryset_list = queryset_list.filter(full_name__icontains=fullname)

    # Location
    if 'location' in request.GET:
        location = request.GET['location']
        for i in location:

            queryset_list = queryset_list.filter(location_city__icontains=i)

    # Categories
    if 'categories' in request.GET:
        categories = request.GET['categories']
        if categories:
            queryset_list = queryset_list.filter(categories__name__iexact=categories)

Функция поиска должна возвращать данные всех категорий и местоположений, по которым производится поиск. Например, если выполняется поиск местоположения Дели и Мумбаи, то он должен вернуть всех тех Влиятельных людей, которые имеют свое местоположение как Дели или Мумбаи, то же самое относится и к категориям.

Функция поиска отлично работает для отдельных значений, но не работает для нескольких значений. Например, если Дели отправляется в категорию местоположения, то он возвращает правильные результаты, но если Дели, Мумбаи выбран, то он считывает только первое значение, то есть Дели, и соответственно применяет фильтр.

Как мне изменить поисковый запрос, чтобы он работал правильно?

2
Ahmad Javed 5 Июл 2019 в 09:03

3 ответа

Лучший ответ

Я думаю, что самый простой подход был бы следующим: использование Q

 from django.db.models import Q
    q = request.GET.get('q')
    if q:
    queryset_list = queryset_list.filter(Q(username__icontains=q)|Q(full_name__icontains=q)|
    Q(location_city__icontains=q)|Q(categories__name__iexact=q))
    return render(....
    else:
        messages.info(request,'no results found for {}',format(q))

И в вашем шаблоне используйте name=q в форме поиска.

  <form  action="{% url 'your search action' %}">
     <input type="text" name="q">
     <input type='submit' value='Search'>
   </form>

ИЛИ вы можете комбинировать ваши all_queries следующим образом:

all_queries = username_queryset_list|fullname_queryset_list|location_queryset_list|
categories_queryset_list
1
arjun 5 Июл 2019 в 07:23

Вот как я выполняю поиск по своим учетным записям: возможные критерии поиска: свободный текст (search_value), выберите группу из поля выбора (sel_group), установите флажок только для активных (chk_active)

    def post(self, request, *args, **kwargs):
        search_value = request.POST.get('searchValue', None)
        sel_group = request.POST.get('selGroup', 'ALL')
        chk_active = request.POST.get('chkActive', 0)

        filters = Q()
        if chk_active == '1':
            filters = filters & Q(is_active=True)
        if sel_group != 'ALL':
            filters = filters & Q(involvements__group__pk=sel_group)

        search_value = None if (search_value == '' or len(search_value) < 3) else search_value
        if search_value is not None:
            filters = filters & Q(last_name__icontains=search_value) | Q(first_name__icontains=search_value) | Q(email__icontains=search_value)

        users = get_user_model().objects.filter(filters)

        context = self.get_context_data(object_list=users)
        return render(request, template_name=self.template_name, context=context)

Надеюсь это поможет ;)

0
cwhisperer 5 Июл 2019 в 06:20

Вы пытались использовать django-filterset для этой цели?

class InfluencerFilter(filters.FilterSet):
username = filters.CharFilter(name='username', lookup_expr='iexact')
fullname = filters.CharFilter(name='fullname', lookup_expr='iexact')
location = filters.NumberFilter(name='location', lookup_expr='exact')
categories = filters.CharFilter(name='categories', lookup_expr='exact')


class Meta:
    model = Influencer
    fields = ['username','fullname','location','categories']

И тогда, на ваш взгляд, вы можете вызвать этот фильтр, используя:

filter_backends = (filters.DjangoFilterBackend,)
filter_class = InfluencerFilter

Это избавит вас от всех утомительных и избыточных операторов if и будет работать только для параметров запроса, которые доступны, и игнорировать остальные.

0
Moeed 5 Июл 2019 в 06:15