我正在努力使用 django queryset 制作具有多条件的搜索功能
I'm struggling with making search function with multi condition using 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=%EC%9D%B8%EC%8A%A4%ED%83%80%EA%B7%B8%EB%9E%A8&follower_num_min=18000
&follower_num_max=&name=&gender=&sns_id=&keyword=
包含我提交但出现 404 错误的条件。我该如何解决这个问题?
您的视图代码可以减少和简化。所有 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)
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=%EC%9D%B8%EC%8A%A4%ED%83%80%EA%B7%B8%EB%9E%A8&follower_num_min=18000
&follower_num_max=&name=&gender=&sns_id=&keyword=
包含我提交但出现 404 错误的条件。我该如何解决这个问题?
您的视图代码可以减少和简化。所有 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)