How do I use a select2 multiple select in a django crispy form?

1.6k views Asked by At

I have an existing crispy form. I want to use django-select2 to replace an existing multi-select with a Select2 field with a maximum of two selections. I know from this post that I need to include 'data-maximum-selection-length' as a widget attribute.

Here is the field code I am adding:

forms.ModelMultipleChoiceField(
required=True, 
queryset=MyModel.objects.all(), 
widget=s2forms.Select2MultipleWidget(attrs={'data-maximum-selection-length': 2}))

I have included {{ form.media.css }} in the head of my template and {{ form.media.js }} before the tag. Edit: I have path('select2/', include('django_select2.urls')), included on my urls.py.

The field is not formatted to appear as a select2 dropdown, it looks like a standard multiselect field.

This is what I'm hoping to obtain: enter image description here ... this is how it looks: enter image description here

I'd be appreciative of any ideas!

References:

2

There are 2 answers

0
Asa LeHolland On

This is not an answer to the above question, but I am including this as the alternative solution to the original issue I implemented.

Essentially I sidestepped the crispy forms issue by injecting the Select2 field I needed in via HTML as a fieldset.


model_ids = [str(ModelObject.id) for obj in ModelInput]
model_ids_string = "".join([f'<option value={model_id}>{model_id}</option>' for model_id in model_ids])

my_fieldset = Fieldset(
    f"""
       <div class="controls">
       <select id="field_name" name="field_name" required 
       class="js-states form-control" style="width:100;" multiple>
       {model_ids_string}
       </select>
       </div>""")
dyn_field_set.append(my_fieldset)

I am not going to accept this answer in case someone has an actual solution that still uses the Select2 object as intended.

0
benAv On

when a very similar situation came up this is what worked, here is the code

views.py

from django_select2.forms import Select2MultipleWidget
class VendorUpdateForm(forms.ModelForm):
   names = forms.ModelMultipleChoiceField(
        queryset=User.objects.filter(is_active=True),
        widget=Select2MultipleWidget(attrs={'data-maximum-selection- 
        length': 2}),
        required=False,
)
    def __init__(self, *args, **kwargs):
        super(VendorUpdateForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.add_input(Submit('submit', 'Submit', css_class='btn- 
         dark'))
        self.helper.form_method = 'POST'

then in the Django template include the necessary js for the select2 to work properly

<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>

{{ form.media.js }}