Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'optgroups' error displaying ManyToMany field as checkboxes #120

Closed
yellowlabrat opened this issue Jul 22, 2022 · 2 comments
Closed

'optgroups' error displaying ManyToMany field as checkboxes #120

yellowlabrat opened this issue Jul 22, 2022 · 2 comments

Comments

@yellowlabrat
Copy link

First time poster, so let me know if this is not the appropriate place for this. :) I've posted on Django Forum and was directed to file an issue here.

I’m attempting to display records from a Many-to-Many field relationship in a ModelForm.

When I load my 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'

treatment_goal field in models.py
treatment_goal = models.ManyToManyField(MyObjective)

MyObjective in models.py (obviously pared down for simplicity)

class MyObjective(TheBaseClass):
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
    objective = models.CharField(max_length=300, default='')

    def __str__(self):
        return str(self.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 for a field that looks like this in models.py:
communication_prefs = MultiSelectField(choices=CommunicationPref.choices, blank=True, default='')

If it helps, CommunicationPref.choices looks like this in models.py:

class CommunicationPref(models.TextChoices):
    PHONE = 'Phone', _('Phone')
    TEXT = 'Text', _('Text')
    EMAIL = 'Email', _('Email')

Again, that is an example of where it is working.

Ultimately, I think the error is indicating that the template being used by crispy-bootstrap5 (radio_checkbox_select.html) does not like the values that are coming back from the ManyToMany field, possibly? The values coming back from the ManyToMany field are a short sentences (strings) as shown in MyObjective code above.

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

Hope that helps explain the issue!

@smithdc1
Copy link
Member

smithdc1 commented Nov 3, 2023

The widgets.CheckboxSelectMultiple code is working fine in another location on forms.py for a field that looks like this in models.py:
communication_prefs = MultiSelectField(choices=CommunicationPref.choices, blank=True, default='')

It seems to me that this MultiSelectField is the issue. As far as I'm aware this isn't a widget that comes with Django. I'm afraid that crispy-forms can't support custom widget (be it in 3rd party packages or from code in user-land).

A custom template for this field would be my recommendation here.

	def __init__(self, *args, **kwargs):
		super().__init__(*args, **kwargs)
		self.helper = FormHelper()
		self.helper.layout = Layout(
			Fieldset('',
				Field('treatment_goal', template="....") # Use Field and provide template name. 
                        )
                )

@smithdc1 smithdc1 closed this as not planned Won't fix, can't repro, duplicate, stale Nov 3, 2023
@yellowlabrat
Copy link
Author

Ah, you are so correct and I didn't think of that back when I posted this! I was so deep into the new project I had forgotten that the MultiSelectField was not official Django.
It comes from this package: https://pypi.org/project/django-multiselectfield/
Thank you for the solution and that makes total sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants