Opened 3 years ago

Closed 3 years ago

#33399 closed Uncategorized (invalid)

Overriding Choices for a field in the Form not working when using ModelForm.

Reported by: Swaroop P Owned by: nobody
Component: Forms Version: 3.0
Severity: Normal Keywords: modelform
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Swaroop P)

Hi All

Facing the following issue after migrating to 3.2.

Example:

class SomeModel(models.Model):
       field1 = models.CharField(choices=[])

class SomeModelForm(forms.ModelForm):

     __init__(*args, **kwargs):
         super().__init__(*args **kwargs)
         self.fields['field1'].choices = <some choices dynamically generated>

    class Meta:
         model = SomeModel
         fields = [ 'field1' ]

In the above case any choice selected is shown with the error "not a valid choice" this is happening because model fields is revalidated again in modelform._post_clean() function.

Intermediate solution is to remove choices from modelfield and reinitalize field in form init wiht dynamic choices. But In previous versions We had choices to only override some attributes of a field rather than reinitalizing whole field.

Thanks

Change History (4)

comment:1 by Swaroop P, 3 years ago

Description: modified (diff)

comment:2 by Swaroop P, 3 years ago

Description: modified (diff)

comment:3 by Swaroop P, 3 years ago

Version: 3.03.2

comment:4 by Mariusz Felisiak, 3 years ago

Resolution: invalid
Status: newclosed
Summary: Overriding Choices for a field in the Form not working when using ModelForm | Django 3.2Overriding Choices for a field in the Form not working when using ModelForm.
Version: 3.23.0

Thanks for the report, it was changed in 16a5a2a2c8d8dbf9cc3e033dd84b986bcaadb963, however it's documented that:

For each model field that has choices set, Django will add a method to retrieve the human-readable name for the field’s current value. See get_FOO_display() in the database API documentation.

Note that choices can be any sequence object – not necessarily a list or tuple. This lets you construct choices dynamically. But if you find yourself hacking choices to be dynamic, you’re probably better off using a proper database table with a ForeignKey. choices is meant for static data that doesn’t change much, if ever.''

choices=[] means that it's set, if you want to get the previous behavior without any validation you shouldn't define choices on a model field, or set choices=None.

Note: See TracTickets for help on using tickets.
Back to Top