Python 搜索 Django 多个属性
Python Django multiple attributes in search
所以我有这个搜索表单:
[医生][专业][城市]
这是HTML中的表格:
<form data-provide="validation" data-disable="true" class="input-glass mt-7" method='POST' action='annuaire/'>
{% csrf_token %}
<div class="row">
<div class="col-md-4">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ti-search mt-1"></i></span>
</div>
<input type="text" class="form-control" placeholder="Doctor's Name" name="kw_name">
</div>
</div>
<div class="col-md-4">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ti-search mt-1"></i></span>
</div>
<select class="form-control" name="kw_specialty">
<option value="" disabled selected>Specialty</option>
{% for spec in specialties %}
<option>{{ spec }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-md-4">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ti-search mt-1"></i></span>
</div>
<select class="form-control" name="kw_city">
<option value="" disabled selected>City</option>
{% for city in cities %}
<option>{{ city }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-md-12">
<button class="btn btn-lg btn-block btn-outline-light" type="submit" name="search_btn">Search</button>
</div>
</div>
</form>
在说我的view.py内容之前,我想先提一下我的问题:搜索表单有很多情况,用户不必填写所有三个过滤器。但是,如果他们将文本输入留空,则结果将是全部。我希望搜索功能在文本字段为空时忽略该文本字段(仅在其中包含值时才考虑它)。此外,如果 2 个下拉列表为 Null(或 None),则该函数会出错。不管怎样,我想要的结果是给出 3 种不同的选择,如果有人使用多个属性,它们都必须是真的,如果选择是空的,它应该被忽略。
这是我的 views.py 文件:
def search(request):
val_name = request.POST.get('kw_name')
val_city = request.POST.get('kw_city')
val_specialty = request.POST.get('kw_specialty')
if val_city is None:
val_city = ''
if val_specialty is None:
val_specialty = ''
if 'search_btn' in request.POST:
if val_city is None:
if val_name is not None:
doctors = Doctor.objects.filter(Q(user__first_name__icontains=val_name) |
Q(user__last_name__icontains=val_name) &
Q(specialty__title__icontains=val_specialty))
else:
doctors = Doctor.objects.filter(Q(user__first_name__icontains=val_name) |
Q(user__last_name__icontains=val_name) &
Q(specialty__title__icontains=val_specialty))
elif val_specialty is None:
doctors = Doctor.objects.filter(Q(user__first_name__icontains=val_name) |
Q(user__last_name__icontains=val_name) &
Q(city__title__icontains=val_city))
elif 'closest_btn' in request.POST:
# deleted because not related to the problem.
context = {
'page_title': 'Résultats des médecins',
'doctors': doctors,
}
return render(request, "dashboard/results.html", context)
感谢您的大力帮助!
PS: 我已经在视图中添加了一些 ifs 和 elses 来尝试解决问题,但它仍然不起作用。有时它会给我不满足任何搜索条件的结果。
我已经能够通过使用字典成功地使用用户过滤器,然后在 filter()
函数中解压它们。对于你的情况,我会尝试如下操作:
def search(request):
val_name = request.POST.get('kw_name', '')
filters = {
'city__title__icontains': request.POST.get('kw_city'),
'specialty__title__icontains': request.POST.get('kw_specialty')
}
filters = {k: v for k, v in filters.items() if v}
q = Q(user__first_name__icontains=val_name) | Q(user__last_name__icontains=val_name)
doctors = Doctor.objects.filter(q, **filters)
context = {
'page_title': 'Résultats des médecins',
'doctors': doctors,
}
return render(request, "dashboard/results.html", context)
所以我有这个搜索表单: [医生][专业][城市]
这是HTML中的表格:
<form data-provide="validation" data-disable="true" class="input-glass mt-7" method='POST' action='annuaire/'>
{% csrf_token %}
<div class="row">
<div class="col-md-4">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ti-search mt-1"></i></span>
</div>
<input type="text" class="form-control" placeholder="Doctor's Name" name="kw_name">
</div>
</div>
<div class="col-md-4">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ti-search mt-1"></i></span>
</div>
<select class="form-control" name="kw_specialty">
<option value="" disabled selected>Specialty</option>
{% for spec in specialties %}
<option>{{ spec }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-md-4">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="ti-search mt-1"></i></span>
</div>
<select class="form-control" name="kw_city">
<option value="" disabled selected>City</option>
{% for city in cities %}
<option>{{ city }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-md-12">
<button class="btn btn-lg btn-block btn-outline-light" type="submit" name="search_btn">Search</button>
</div>
</div>
</form>
在说我的view.py内容之前,我想先提一下我的问题:搜索表单有很多情况,用户不必填写所有三个过滤器。但是,如果他们将文本输入留空,则结果将是全部。我希望搜索功能在文本字段为空时忽略该文本字段(仅在其中包含值时才考虑它)。此外,如果 2 个下拉列表为 Null(或 None),则该函数会出错。不管怎样,我想要的结果是给出 3 种不同的选择,如果有人使用多个属性,它们都必须是真的,如果选择是空的,它应该被忽略。
这是我的 views.py 文件:
def search(request):
val_name = request.POST.get('kw_name')
val_city = request.POST.get('kw_city')
val_specialty = request.POST.get('kw_specialty')
if val_city is None:
val_city = ''
if val_specialty is None:
val_specialty = ''
if 'search_btn' in request.POST:
if val_city is None:
if val_name is not None:
doctors = Doctor.objects.filter(Q(user__first_name__icontains=val_name) |
Q(user__last_name__icontains=val_name) &
Q(specialty__title__icontains=val_specialty))
else:
doctors = Doctor.objects.filter(Q(user__first_name__icontains=val_name) |
Q(user__last_name__icontains=val_name) &
Q(specialty__title__icontains=val_specialty))
elif val_specialty is None:
doctors = Doctor.objects.filter(Q(user__first_name__icontains=val_name) |
Q(user__last_name__icontains=val_name) &
Q(city__title__icontains=val_city))
elif 'closest_btn' in request.POST:
# deleted because not related to the problem.
context = {
'page_title': 'Résultats des médecins',
'doctors': doctors,
}
return render(request, "dashboard/results.html", context)
感谢您的大力帮助!
PS: 我已经在视图中添加了一些 ifs 和 elses 来尝试解决问题,但它仍然不起作用。有时它会给我不满足任何搜索条件的结果。
我已经能够通过使用字典成功地使用用户过滤器,然后在 filter()
函数中解压它们。对于你的情况,我会尝试如下操作:
def search(request):
val_name = request.POST.get('kw_name', '')
filters = {
'city__title__icontains': request.POST.get('kw_city'),
'specialty__title__icontains': request.POST.get('kw_specialty')
}
filters = {k: v for k, v in filters.items() if v}
q = Q(user__first_name__icontains=val_name) | Q(user__last_name__icontains=val_name)
doctors = Doctor.objects.filter(q, **filters)
context = {
'page_title': 'Résultats des médecins',
'doctors': doctors,
}
return render(request, "dashboard/results.html", context)