#34711: form.has_changed() is always True for IntegerChoices Enum Model Field
------------------------+--------------------------------------
Reporter: GHPS | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 4.2
Severity: Normal | Resolution:
Keywords: | 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 GHPS:
Old description:
> Summary:
>
> While trying to find out why the forms in two different applications are
> marked for saving even if no field has been changed, I could pin the
> problem down
> to the integer enum fields used in both models and form.ChoiceField
> involved.
> In short form.has_changed() is triggered because of a double data
> conversion
> during the round-trip.
>
> The value of the integer enum field is converted to a string and
> rendered.
> The POST request comes back with this string which gets compared to the
> original
> enum integer which shows that they are different. During the -
> unnecessary - saving
> the string becomes an int again - which is why the original problem is
> hidden
> from the perspective of a user.
>
> Background:
>
> In Django 4.2 on Linux (Kubuntu 22.04) take the following enum and
> create a model field in model.py:
>
> {{{
> class eAssets(models.IntegerChoices):
> dvd =1, _('DVD')
> bluray =3, _('Blu-ray')
> none =0, _('-')
>
> eAsset=models.PositiveSmallIntegerField(choices=eAssets.choices,
> default=eAssets.none)
> }}}
>
> Create a choice form field in form.py:
>
> {{{
> eAsset=forms.ChoiceField(label=mdMovie._meta.get_field('eAsset').verbose_name,
> choices=[(dcEntry.value, dcEntry.label) for dcEntry in mdMovie.eAssets],
> initial=mdMovie.eAssets.none)
>
> After processing the POST request, form.has_changed() is always true in
> view.py:
>
> >fmForm=fmMovie(vRequest.POST, vRequest.FILES or None,
> instance=rcCurrentMovie)
> >fmForm.has_changed()
> True
> >fmForm.changed_data
> ['eAsset']
> }}}
>
> Links:
> - I've found an old ticket #22097 and it looks to me like this nine year
> old bug has shown its ugly face again.
> - On Stackoverflow someone reported the same problem.
> [https://stackoverflow.com/questions/68763230/django-forms-a-dynamic-
> integer-model-choice-field-always-fails-form-has-changed|A dynamic
> integer model choice field always fails form.has_changed()]
New description:
Summary:
While trying to find out why the forms in two different applications are
marked for saving even if no field has been changed, I could pin the
problem down
to the integer enum fields used in both models and form.ChoiceField
involved.
In short, form.has_changed() is triggered because of a double data
conversion
during the round-trip.
The value of the integer enum field is converted to a string and rendered.
The POST request comes back with this string which gets compared to the
original
enum integer which shows that they are different. During the - unnecessary
- saving
the string becomes an int again - which is why the original problem is
hidden
from the perspective of a user.
This bug seem to be a regression from bug #22097.
Background:
In Django 4.2 on Linux (Kubuntu 22.04) take the following enum and
create a model field in model.py:
{{{
class eAssets(models.IntegerChoices):
dvd =1, _('DVD')
bluray =3, _('Blu-ray')
none =0, _('-')
eAsset=models.PositiveSmallIntegerField(choices=eAssets.choices,
default=eAssets.none)
}}}
Create a choice form field in form.py:
{{{
eAsset=forms.ChoiceField(label=mdMovie._meta.get_field('eAsset').verbose_name,
choices=[(dcEntry.value, dcEntry.label) for dcEntry in mdMovie.eAssets],
initial=mdMovie.eAssets.none)
}}}
After processing the POST request, form.has_changed() is always true in
view.py:
{{{
>fmForm=fmMovie(vRequest.POST, vRequest.FILES or None,
instance=rcCurrentMovie)
>fmForm.has_changed()
True
>fmForm.changed_data
['eAsset']
}}}
Links:
- I've found an old ticket #22097 and it looks to me like this nine year
old bug has shown its ugly face again.
- On Stackoverflow someone reported the same problem.
[https://stackoverflow.com/questions/68763230/django-forms-a-dynamic-
integer-model-choice-field-always-fails-form-has-changed|A dynamic integer
model choice field always fails form.has_changed()]
--
--
Ticket URL: <https://code.djangoproject.com/ticket/34711#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018955bf4f13-7c474ca3-2750-4401-92eb-c5494afb0f57-000000%40eu-central-1.amazonses.com.