Я борюсь с созданием функции поиска с несколькими условиями, используя django queryset

#python #django #django-queryset

#python #django #django-queryset

Вопрос:

 def influencer_board(request):
    user_input = []
    index_list = []
    influencer = Influencer_DB.objects.all()
    if request.method == 'GET':
        sns_type = request.GET.get('sns_type') #0
        follower_num_min = request.GET.get('follower_num_min') #1
        follower_num_max = request.GET.get('follower_num_max') #2
        name = request.GET.get('name')#3
        gender = request.GET.get('gender')#4
        sns_id = request.GET.get('sns_id')#5
        keyword = request.GET.get('keyword')#6

        user_input.append(sns_type)
        user_input.append(follower_num_min)
        user_input.append(follower_num_max)
        user_input.append(name)
        user_input.append(gender)
        user_input.append(sns_id)
        user_input.append(keyword)

        for col in user_input:
            if col != "":
                index = user_input.index(col)
                index_list.append(index)

        influencer = Influencer_DB.objects
        for index in index_list:
            if index == 0:
                influencer = influencer.filter(sns_type=sns_type)
            if index == 1:
                influencer = influencer.filter(follower_num__gte = follower_num_min)
            if index == 2:
                influencer = influencer.filter(follower_num__lte = follower_num_max)
            if index == 3:
                influencer = influencer.filter(name=name)
            if index == 4:
                influencer = influencer.filter(gender = gender)
            if index == 5:
                influencer = influencer.filter(sns_id=sns_id)
            if index == 6:
                influencer = influencer.filter(keyword__icontains = keyword)

        return render(request,"influencer_board.html",{'influencer':influencer,"sns_type":sns_type,'follower_num_max':follower_num_max, 'followever':follower_num_min,'name':name, 'gender':gender,'sns_id':sns_id,'keyword':keyword})
    return render(request,"influencer_board.html",{'influencer':influencer})
  

urls.py

 from django.contrib import admin
from django.urls import path, include
from main.views import main, go_back_and_clean,create_contract,show_record,confirm,delete,wait,delete_contract,celly_btn_info,btn_push,btn_create,btn_delete
from main.views import btn_condition_change
from login.views import login,logout,signup
from influencer_db.views import influencer_board

urlpatterns = [
    path('admin/', admin.site.urls),
    path('home/',main,name='home'),
    path('delete/', go_back_and_clean, name="delete"),
    path('',login, name='login'),
    path('logout/',logout, name='logout'),
    path('sign_up/',signup, name='signup'),
    path('create_contract/',create_contract,name='create_contract'),
    path('contract_board/<int:contract_id>',show_record,name='contract_board'),
    path('confirm/<int:record_id><int:contract_id>',confirm,name='confirm'),
    path('delete/<int:record_id><int:contract_id>',delete,name='delete'),
    path('wait/<int:record_id><int:contract_id>',wait,name='wait'),
    path('delete_contract/<int:contract_id>',delete_contract,name='delete_contract'),
    path('btn_info/<int:btn_id>',celly_btn_info,name='btn_info'),
    path('btn_push/<int:btn_id>',btn_push, name="btn_push"),
    path('btn_create/',btn_create,name='btn_create'),
    path('btn_delete/<int:btn_id>', btn_delete, name='btn_delete'),
    path('btn_condition_change/<int:btn_id>', btn_condition_change, name='btn_condtion_change'),
    path('influencer_board/',influencer_board,name="internal_influencer"),
  

Как и в приведенном выше коде, я получаю 7 условий поиска от пользователя. Также, если пользователь вводит менее 7 условий, я все равно хочу фильтровать базу данных по этим условиям. Тем не менее, он продолжает делать эту ошибку:

введите описание изображения здесь

функция, похоже, работает правильно, потому что URL

 http://127.0.0.1:8000/influencer_board/GET?
  sns_type=인스타그램amp;follower_num_min=18000
  amp;follower_num_max=amp;name=amp;gender=amp;sns_id=amp;keyword=
  

содержит условия, которые я отправил, но допустил ошибку 404. Как я могу решить эту проблему?

Комментарии:

1. Пожалуйста, покажите свой urls.py

2. URL /influencer_board/GET -адрес не существует в вашем URL conf, и показанное вами представление также не перенаправляет на этот URL. Итак, откуда этот запрос? Можете ли вы показать шаблон, который отправляет этот запрос?

Ответ №1:

Ваш код представления может быть сокращен и упрощен. Все 7 полей имеют схожую логику фильтрации, поэтому мы можем создать список полей для фильтрации (включая их фильтр полей типа __icontains и __gte ) и перебирать этот список вместо того, чтобы писать почти одно и то же 7 раз.

Вот предложение, которое должно иметь ту же функциональность с меньшим количеством кода.

 FILTER_KEYS = (
    ('sns_type', 'sns_type'),
    ('follower_num_min', 'follower_num__gte'),
    ('follower_num_max', 'follower_num__lte'),
    ('name', 'name'),
    ('gender', 'gender'),
    ('sns_id', 'sns_id'),
    ('keyword', 'keyword__icontains'),
)

def influencer_board(request):
    qs = Influencer_DB.objects.all()
    ctx = {}

    if request.method == 'GET':
        for key, field_with_filter in FILTER_KEYS:
            v = request.GET.get(key, '').strip()
            if len(v) == 0:
                # it's empty, so skip this
                continue

            # filter the QuerySet
            qs = qs.filter(**{field_with_filter: v})

            # add to context for template rendering
            ctx[key] = v

    # add to context for template rendering
    ctx['influencer'] = qs

    return render(request, "influencer_board.html", ctx)