[Django] #33399: Overriding Choices for a field in the Form not working when using ModelForm | Django 3.2

17 views
Skip to first unread message

Django

unread,
Dec 30, 2021, 1:08:52 AM12/30/21
to django-...@googlegroups.com
#33399: Overriding Choices for a field in the Form not working when using ModelForm
| Django 3.2
-----------------------------------------+---------------------------
Reporter: Swaroop P | Owner: nobody
Type: Uncategorized | Status: new
Component: Forms | Version: 3.0
Severity: Normal | Keywords: modelform
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+---------------------------
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'] = <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

--
Ticket URL: <https://code.djangoproject.com/ticket/33399>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 30, 2021, 1:09:40 AM12/30/21
to django-...@googlegroups.com
#33399: Overriding Choices for a field in the Form not working when using ModelForm
| Django 3.2
-------------------------------+--------------------------------------

Reporter: Swaroop P | Owner: nobody
Type: Uncategorized | Status: new
Component: Forms | Version: 3.0
Severity: Normal | Resolution:

Keywords: modelform | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by Swaroop P:

Old description:

> 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'] = <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

New description:

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'] = <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

--

--
Ticket URL: <https://code.djangoproject.com/ticket/33399#comment:1>

Django

unread,
Dec 30, 2021, 1:11:30 AM12/30/21
to django-...@googlegroups.com
#33399: Overriding Choices for a field in the Form not working when using ModelForm
| Django 3.2
-------------------------------+--------------------------------------

Reporter: Swaroop P | Owner: nobody
Type: Uncategorized | Status: new
Component: Forms | Version: 3.0
Severity: Normal | Resolution:

Keywords: modelform | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by Swaroop P:

Old description:

> 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'] = <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

New description:

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

--

--
Ticket URL: <https://code.djangoproject.com/ticket/33399#comment:2>

Django

unread,
Dec 30, 2021, 1:26:39 AM12/30/21
to django-...@googlegroups.com
#33399: Overriding Choices for a field in the Form not working when using ModelForm
| Django 3.2
-------------------------------+--------------------------------------

Reporter: Swaroop P | Owner: nobody
Type: Uncategorized | Status: new
Component: Forms | Version: 3.2
Severity: Normal | Resolution:

Keywords: modelform | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Swaroop P):

* version: 3.0 => 3.2


--
Ticket URL: <https://code.djangoproject.com/ticket/33399#comment:3>

Django

unread,
Dec 30, 2021, 1:55:53 AM12/30/21
to django-...@googlegroups.com
#33399: Overriding Choices for a field in the Form not working when using
ModelForm.
-------------------------------+--------------------------------------

Reporter: Swaroop P | Owner: nobody
Type: Uncategorized | Status: closed
Component: Forms | Version: 3.0
Severity: Normal | Resolution: invalid

Keywords: modelform | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* version: 3.2 => 3.0
* resolution: => invalid


Comment:

Thanks for the report, it was changed in
16a5a2a2c8d8dbf9cc3e033dd84b986bcaadb963, however it's
[https://docs.djangoproject.com/en/4.0/ref/models/fields/#django.db.models.Field.choices
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`.

--
Ticket URL: <https://code.djangoproject.com/ticket/33399#comment:4>

Reply all
Reply to author
Forward
0 new messages