Error displaying ManyToMany field as checkboxes with django-crispy-forms

Hello,

I’m attempting to display records from a Many-to-Many field relationship in a ModelForm that uses django-crispy-forms.

When I load the page/template in the browser, I see the following error:

File "...path here.../lib/python3.9/site-packages/django/template/base.py", line 569, in find_filter
    raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
django.template.exceptions.TemplateSyntaxError: Invalid filter: 'optgroups'

field in models.py

treatment_goal = models.ManyToManyField(Objective)

form in forms.py

class MyForm(ModelForm):
	class Meta:
		model = MyModel
		widgets = {
			'treatment_goal': widgets.CheckboxSelectMultiple
		}

	def __init__(self, *args, **kwargs):
		super().__init__(*args, **kwargs)
		self.helper = FormHelper()
		self.helper.layout = Layout(
			Fieldset('',
				'treatment_goal',
            )
        )

If I don’t use the widgets.CheckboxSelectMultiple code, it renders the field as a Multi-Select field and works fine. But the moment I add the CheckboxSelectMultiple code, it gives the error.

The widgets.CheckboxSelectMultiple code is working fine in another location on forms.py, so I think the error is indicating that the template being used by django-crispy-forms (radio_checkbox_select.html) does not like the values that are coming back from the ManyToMany field, possibly?

This is the radio_checkbox_select.html file being used:
https://github.com/django-crispy-forms/crispy-bootstrap5/blob/main/crispy_bootstrap5/templates/bootstrap5/layout/radio_checkbox_select.html

Any help is greatly appreciated!

So that link leads me to believe that you’re using the crispy-bootstrap5 template pack.

Can you try this without that template pack? It would be nice to try and isolate this between being a Django issue and a “crispy-boostrap5” template issue.

It looks like that last release of that package was about 3 months before Django 4.0 was released. It’s possible that the released version is not Django 4.0 compatible. You may need to build it directly from the repo.

Thank you for the reply!

I am using the crispy-bootstrap5 template pack. But I am also still on Django 3.2.8.

I took your advice and removed the crispy-bootstrap5 pack from the equation by doing the following:

views.py:
Switched to a different template name.

forms.py:
Created a different version that did not use django-crispy-forms…

class MyForm(ModelForm):
	treatment_goal = ModelMultipleChoiceField(
				queryset=Objective.objects.all(),
				widget=CheckboxSelectMultiple
			)

	class Meta:
		model = MyModel
		fields = ['treatment_goal']

This rendered the field as expected, as checkboxes.
So, my question now is, what does this error mean, when I’m using the radio_checkbox_select.html template:
Invalid filter: ‘optgroups’

Looking at line 6 of the above link, this seems to be the part it is breaking on:

{% for group, options, index in field|optgroups %}

I’m a newbie and I’ve built my whole project around django-crispy-forms and Bootstrap5 and can’t just remove all of it for the generic form rendering. Any advice on how to proceed is appreciated!
Do I need to write this up on the crispy-bootstrap5 GitHub repo as an issue?
Should I write a different version of the “radio_checkbox_select.html” template it is using?
Not sure where to go from here.

The optgroups filter is defined in that crispy-bootstrap5 package. It’s not a standard Django filter.

Yes, I’d start with checking the github repo to see if it’s a current issue, and writing one up if there isn’t one already.

(Do you know if you have other templates that are actually using that filter? Is it possible there’s an installation issue where Django isn’t finding the filter?)

Or you could try debugging it, I’m sure the maintainer(s) would love to have a patch that resolves it. Or you could replace it with a different template. Or you could create a modified version of CheckboxSelectMultiple that works with it.

I don’t have a specific recommendation for you here - it’s all an issue of what you feel comfortable with doing and how quickly you need it resolved. (The “expedient” solution frequently isn’t the “best” or most “correct” solution…)

Sorry I don’t have any real help to provide here - while I rely heavily on crispy-forms, we’re not on bootstrap5.

Ok, I submitted an issue on that repo:
https://github.com/django-crispy-forms/crispy-bootstrap5/issues/120

Do you know if you have other templates that are actually using that filter? Is it possible there’s an installation issue where Django isn’t finding the filter?

Yes, I have other fields that are using it successfully, but their model uses the MultiSelectField:

communication_prefs = MultiSelectField(choices=CommunicationPref.choices, blank=True, default='')

Or you could try debugging it, I’m sure the maintainer(s) would love to have a patch that resolves it. Or you could replace it with a different template. Or you could create a modified version of CheckboxSelectMultiple that works with it.

I’m not sure how to do any of these things yet, so I’ll try to look into them as well.

Thanks for your help so far!