Как я могу фильтровать таблицу результатов с несколькими формами/многими вариантами в одной форме в 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)