Django Select2: How to write a auto select dropdown form with django select2
abhishek-ntt opened this issue · comments
Hi, I'm writing a form @applegrew
forms/invoices.py
from django import forms
from django_select2.forms import ModelSelect2Widget
class CreditNoteFilterForm(forms.Form):
credit_note_id = LimitedIntegerField(label="Credit Note ID",
required=False, help_text="CN")
customer = forms.ChoiceField(
label="Choose customer", required=False,
widget=ModelSelect2Widget(model=Customer,
queryset = Customer.objects.all().exclude(is_active=False),
search_fields = ["customer_name__istartswith",
"description__istartswith",
"user__first_name__istartswith",
"user__last_name__istartswith",
]),
)
template - templates/invoice/list.html
{% if filter_form %}
<div id="toolbar" class="search-form">
<form method="get" action="" id="changelist-search" class="changelist-search">
<table>
{{ filter_form.as_table }}
<tr>
<td></td>
<td>
<input name="form_search_button" type="submit" value="Filter">
{% block new_object_link %}
<a class="link" href="{% url 'new_invoice' %}">New invoice</a>
{% endblock new_object_link %}
</td>
</tr>
</table>
</form>
</div>
{% endif %}
and a class based view
views/invoices/listings.py
class BaseInvoiceLikeListView(ListView):
def get_context_data(self, **kwargs):
context = super(BaseInvoiceLikeListView, self).get_context_data(**kwargs)
order_by_query, field, direction = get_order_by_from_request(
self.request, self.columns)
context["title"] = self.title
context["sorting"] = field
context["sorting_direction"] = direction
context["columns"] = self.columns
def get_filter_form(self):
if not hasattr(self, "filter_form"):
request = self.request
self.filter_form = self.filter_form_class(request.GET)
self.valid_filter_form = self.filter_form.is_valid()
return self.valid_filter_form, self.filter_form
def filter_with_form(self, qs):
valid, form = self.get_filter_form()
if valid:
pk = form.cleaned_data.get(self.filter_key)
customer = form.cleaned_data.get("customer")
if pk:
qs = qs.filter(pk=pk)
if customer:
qs = qs.filter(customer__id=customer.id)
return qs
def get_queryset(self):
qs = super(BaseInvoiceLikeListView, self).get_queryset()
qs = self.filter_with_form(qs)
qs = self.sort_orders_queryset(qs)
return qs
Application is running and we can see the Customer dropdown box and if we enter 2 letters it will start displaying the customers with those letters and once we select the customer and click on submit button, it is showing the error as Select a valid choice. 814 is not one of the available choices. But it is a valid customer id and there is a database record and after submit, the selected option is not selected in the form.
Hi @abhishek-ntt,
thanks for reaching out. I believe you are seeing this validation error, because you didn't pass any choices to your forms.ChoiceField
. So even if the widget shows choices, the Django's form validation will think they are not valid. I would advise you to use a forms.ModelChoiceField
and also pass the same queryset, that you pass to the widget queryset=Customer.objects.all().exclude(is_active=False)
.
I hope that solves your problem. If not, please reach out any time.
Best
-Joe