Как я могу фильтровать таблицу результатов с несколькими формами/многими вариантами в одной форме в django?

Я хочу иметь одну страницу с несколькими вариантами фильтра (например, название, аббревиатура, страна, ...), где вы можете ввести в форму Sweden и получить результаты только по учреждениям в Швеции ИЛИ ввести название/аббревиатуру/... при нажатии кнопки "поиск". Кнопка поиска перенаправляет вас в таблицу отфильтрованных результатов.

forms.py

class InstitutionsForm(forms.Form):
     name = forms.CharField(label='Name', required=False)
     abbreviation = forms.CharField(label='Abbreviation', required=False)

views.py

def institution_search_form(request):
    if request.method == "POST":
        form = InstitutionsForm(request.POST)
        if form.is_valid():
            return institution_results_name(request, form)  
    else:
        context = {
            "form": InstitutionsForm
        }
        return render(request,"stakeholders/institution_form.html", context)

def institution_results_name(request, form):
    all_insts = Institution.objects.filter(name=form.cleaned_data["name"])
    context = {
    "result_data":=SafeString(serializers.serialize("json", all_insts)),
    }
    return render(request, "landing/result_table.html", context)

institution_form.html

<form method="post">
  {{ form.as_p }}
  {% csrf_token %}
  <input type="submit" value="Search">
</form>

Пока что я получаю все поля CharFields, которые я определил в forms.py, на одной странице.

Моя проблема в том, что я не могу искать по странам, аббревиатуре и т.д. Только 'Name' работает.

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

Я также пытался написать различные представления для каждой формы и везде заменил 'name' на 'country', но все равно не могу получить правильные результаты.

def institution_results_country(request, form):
    all_insts = Institution.objects.filter(name=form.cleaned_data["country"])
    context = {
    "result_data":=SafeString(serializers.serialize("json", all_insts)),
    }
    return render(request, "landing/result_table.html", context)

(то же самое с формой institution_search_form. -> institution_search_form_country().... return institution_country())

Надеюсь, кто-нибудь сможет мне помочь! Все идеи приветствуются :)

В вашем случае (работает только имя) это связано с тем, что вы указываете имя в методе filter. Если вам нужно фильтровать по другим полям, то укажите и их. Для получения дополнительной информации смотрите официальную документацию.

Итак, если вы хотите фильтровать на основе двух столбцов имя и страна, то ваша функция будет выглядеть следующим образом:

def institution_results_country(request, form):
    all_insts = Institution.objects.filter(name=form.cleaned_data["name"], country=form.cleaned_data["country"])
    context = {
    "result_data":=SafeString(serializers.serialize("json", all_insts)),
    }
    return render(request, "landing/result_table.html", context)

Работает это следующим образом. Вы должны создать форму с тремя полями: имя, аббревиатура и страна. Все эти поля должны иметь значение required=False. Ниже приведен код для формы.

# Your form 
class SearchInstitutionsForm(forms.Form):
    name = forms.CharField(required=False)
    abbreviation = forms.CharField(required=False)
    country = forms.CharField(required=False)

Теперь в представлении поиска вам нужно отфильтровать на основе полей, которые были заполнены пользователем. Ваше представление будет выглядеть следующим образом.

    # Your search view
    def search_institutions(request):
        form = SearchInstitutionsForm()
        qs = Institution.objects.all()
        if request.method == "POST":
            form = SearchInstitutionsForm(request.POST)
            if form.is_valid():
                cd = form.cleaned_data
                if cd['name']:
                    qs = Institution.objects.filter(name__contains=cd['name'])
                if cd['abbreviation']:
                    qs = Institution.objects.filter(
                        abbreviation__contains=cd['abbreviation'])
                if cd['country']:
                    qs = Institution.objects.filter(
                        country__contains=cd['country']
                    )
        
        context {
            'result_data':=SafeString(serialize.serialize("json", qs)),
            'form': form
        }
        return render(request, "landing/result_table.html", context)
Вернуться на верх