I have a form in django with a ModelMultipleChoiceField, but when I submit the data, I have the same parameter repeated in the url for every selected option (like localhost:8000/search/?category=1&category=2
).
Here's a toy example:
#forms.py
class SearchForm(forms.ModelForm):
category = forms.ModelMultipleChoiceField(Category.objects.all(), required=False)
class Meta:
model = Document
fields = ("start_date", "end_date", "category")
#views.py
class SearchResultsView(ListView, FormView):
model = Document
template_name = "archive/document_list.html"
context_object_name = "documents"
form_class = SearchForm
def get_queryset(self):
object_list = Document.objects.all()
if start_date := self.request.GET.get("start_date"):
object_list = object_list.filter(date__gte=start_date)
if end_date := self.request.GET.get("end_date"):
object_list = object_list.filter(date__lte=end_date)
if category := self.request.GET.get("category"):
object_list = object_list.filter(
category__name=category,
)
return object_list.distinct()
In the template:
<form action="{% url 'search_results' %}" method="get">
<div class="flexline flex-wrap justify-content">
{{ form|materializecss }}
<div>
<button class="btn" type="submit">Submit</button>
</div>
</form>
The form is displayed correctly:
But when I click submit I get the following url:
http://localhost:8000/search/?start_date=&end_date=&category=1&category=2
Having same keys in query params is the normal behavior.
You can use getlist
function in your view to make it work. Something like this:
if categories := self.request.GET.getlist("category", []):
object_list = object_list.filter(
category__id__in=categories,
)