Opened 12 years ago
Closed 12 years ago
#22354 closed Bug (invalid)
ModelForm has_changed on ChoiceFields reports always True if an initial argument is given
| Reported by: | s3h10r | Owned by: | nobody |
|---|---|---|---|
| Component: | Forms | Version: | 1.6 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
example model + form:
class Host(models.Model):
DM=0
PP=1
KIND_CHOICES = (
(DM, 'native mpio'),
(PP, 'PowerPath'),
)
mpio = models.IntegerField(choices=KIND_CHOICES, default=DM)
class HostForm(ModelForm):
DM=0
PP=1
KIND_CHOICES = (
(DM, 'native mpio'),
(PP, 'PowerPath'),
)
mpio = forms.ChoiceField(choices=KIND_CHOICES, label="Multipathing Software", required=True, initial=DM)
class Meta:
model = Host
testcase:
from formprob16.models import Host
from formprob16.forms import HostForm
fm = HostForm() # unbound
fm = HostForm({'mpio' : 0 }) # bound
print "has_changed:", fm.has_changed()
print "changed_data:", fm.changed_data
output in Django 1.5.5 (and 1.4) is as expected:
>>> has_changed: False >>> changed_data: []
output in Django 1.6.2 says the form-content was changed:
>>> has_changed: True >>> changed_data: ['mpio']
If the initial argument is not used / the Form is just derived from the model like in the following example:
class HostForm(ModelForm):
class Meta:
model = Host
it works fine in 1.6.2 too, but i think that's not the expected behaviour (or: at least not expected by me ;).
Change History (3)
comment:1 by , 12 years ago
comment:2 by , 12 years ago
@claudep: Thanks! I wasn't aware of this / just stumbled into the pitfall of changed behaviour (could not find much about .has_changed() in the docs). TypedChoiceField works fine.
comment:3 by , 12 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
#21792 is for documenting ModelForm.has_changed().
I can reproduce what you describe. However, the proper field to use here should be a
TypedChoiceField(..., coerce=int). I'll keep the ticket open to see if another core developer has another opinion on the matter, or if something should be added in the documentation.