So I have this search form: [Doctor][Specialty][City]
This is the form in 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>
Before I talk about my view.py content, I would like to mention my problem first: The search form has many cases, and the users don't have to fill all three filters. But if they leave the text input empty, the results will be ALL. I want the search function to ignore the text field if it's empty (only consider it if it has a value in it). Also, if the 2 dropdowns are Null (or None) the function gives an error. Anyways my desired outcome would be to give 3 different choices to choose from, and if someone uses more than one attributes, they all have to be true, if a selection is empty, it should be ignored.
Here is my views.py file:
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)
Thank you for your great help!
PS: I already put some ifs and elses in the view to try to solve the issue but it's still not working. Sometimes it gives me results that don't satisfy any of the search criteria.