Расширенный поиск в Django с несколькими полями и сохранением фильтров в пагинации

У меня есть этот кусок кода, который уже работает. Он позволяет вам иметь форму поиска, для поиска в определенной таблице с несколькими фильтрами. Результаты постраничные, и эта форма позволяет сохранить эти фильтры при просмотре нескольких страниц.

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я повторно использую этот кусок кода в другом сценарии, и он включает проверку одного фильтра в нескольких полях в таблице базы данных.

Пример стандартного сценария:

  1. Первое имя
  2. Последнее имя
  3. Город

В этом случае вид будет таким:

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>

Теперь, текущий сценарий, в котором мы имеем проблему, таков:

Теперь вы хотите выполнить поиск, используя тот же фильтр, в нескольких полях, например:

  1. Первое имя
  2. Последнее имя
  3. Деятельность
  4. Город

А ваша модель, допустим, такая:

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)
Вернуться на верх