Расширенный поиск в Django с несколькими полями и сохранением фильтров в пагинации
У меня есть этот кусок кода, который уже работает. Он позволяет вам иметь форму поиска, для поиска в определенной таблице с несколькими фильтрами. Результаты постраничные, и эта форма позволяет сохранить эти фильтры при просмотре нескольких страниц.
Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я повторно использую этот кусок кода в другом сценарии, и он включает проверку одного фильтра в нескольких полях в таблице базы данных.
Пример стандартного сценария:
- Первое имя
- Последнее имя
- Город
В этом случае вид будет таким:
def clean_filters(filters):
filters = {k: v for k, v in filters.items() if v}
return filters
def search(request):
filters = {
"user__first_name__icontains": request.GET.get("fname_kw"),
"user__last_name__icontains": request.GET.get("lname_kw"),
"city__name__icontains": request.GET.get("city_kw"),
}
html_queries = {
"fname_kw": request.GET.get("fname_kw"),
"lname_kw": request.GET.get("lname_kw"),
"city_kw": request.GET.get("city_kw"),
}
filters = clean_filters(filters)
html_queries = clean_filters(html_queries)
people = Person.objects.filter(**filters)
page_num = request.GET.get("page", 1)
p = Paginator(people.order_by("-pk"), 12)
people = p.get_page(page_num)
context = {
"people": people,
"cities": City.objects.all(),
"filters": html_queries,
}
return render(request, "pages/index.html", context)
И HTML будет выглядеть следующим образом:
<form method="GET" action="{% url 'search' %}">
<div class="row">
<div class="col-xl-3 col-lg-3 col-md-3 col-sm-12 col-xs-12">
<div class="row">
<div class="col-6">
<input class="form-control" name="fname_kw" id="search_fname" placeholder="First Name" />
</div>
<div class="col-6">
<input class="form-control" name="lname_kw" id="search_lname" placeholder="Last Name" />
</div>
</div>
</div>
<div class="col-xl-3 col-lg-3 col-md-3 col-sm-12 col-xs-12">
<select class="form-control" name="city_kw" id="search_city" placeholder="test" >
<option value="" disabled selected>Ville</option>
{% for c in cities %}
<option value={{ c }}>{{ c.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-xl-3 col-lg-3 col-md-3 col-sm-12 col-xs-12">
<div class="row">
<div class="col-6">
<button class="btn btn-success" style="width:100%;" type="submit">Search</button>
</div>
<div class="col-6">
<button class="btn btn-danger" style="width:100%;">Reset</button>
</div>
</div>
</div>
</div>
</form>
Теперь, текущий сценарий, в котором мы имеем проблему, таков:
Теперь вы хотите выполнить поиск, используя тот же фильтр, в нескольких полях, например:
- Первое имя
- Последнее имя
- Деятельность
- Город
А ваша модель, допустим, такая:
class Model(models.Model):
first_name = models.CharField()
last_name = models.CharField()
activity1 = models.ForeignKey(Activity)
activity2 = models.ForeignKey(Activity)
activity3 = models.ForeignKey(Activity)
city = models.ForeignKey(City)
Что можно изменить в приведенном выше коде, чтобы это заработало? Я уже сделал это, но это не работает:
def search(request):
filters = {
"user__first_name__icontains": request.GET.get("fname_kw"),
"user__activity1__icontains": request.GET.get("activity_kw"),
"user__activity2__icontains": request.GET.get("activity_kw"),
"user__activity3__icontains": request.GET.get("activity_kw"),
"user__last_name__icontains": request.GET.get("lname_kw"),
"city__name__icontains": request.GET.get("city_kw"),
}
html_queries = {
"fname_kw": request.GET.get("fname_kw"),
"lname_kw": request.GET.get("lname_kw"),
"activity_kw": request.GET.get("activity_kw"),
"city_kw": request.GET.get("city_kw"),
}
filters = clean_filters(filters)
html_queries = clean_filters(html_queries)
people = Person.objects.filter(**filters)
page_num = request.GET.get("page", 1)
p = Paginator(people.order_by("-pk"), 12)
people = p.get_page(page_num)
context = {
"people": people,
"cities": City.objects.all(),
"activities": Activity.objects.all(),
"filters": html_queries,
}
return render(request, "pages/index.html", context)