[Django] #25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9

21 views
Skip to first unread message

Django

unread,
Dec 15, 2015, 1:27:26 PM12/15/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
----------------------------+--------------------
Reporter: arthru | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.9
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------+--------------------
We've met a strange bug with Django 1.9 on TypedChoiceField.has_changed.

We encountered the bug when using a TypedChoiceField in a form of a
formset. When we have an empty extra form, and we submit all the form, the
submitted form is not validated due to some "changes" made to the
TypedChoiceFields.

The excepted behavior would be to save the formset data without treating
that extra form.

I finally found that the method has_changed of a field has been modified
from 1.8, and calls self._coerce for the initial value. By removing it, my
use case now works like expected.

I attach to this ticket a unit test that reproduces my case.

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

Django

unread,
Dec 15, 2015, 1:27:59 PM12/15/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
--------------------+----------------------------

Reporter: arthru | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.9
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Easy pickings: 0
UI/UX: 0 |
--------------------+----------------------------
Changes (by arthru):

* Attachment "test.patch" added.

Unit test

Django

unread,
Dec 15, 2015, 5:03:21 PM12/15/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
---------------------------------+------------------------------------

Reporter: arthru | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.9
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
---------------------------------+------------------------------------
Changes (by timgraham):

* needs_docs: => 0
* needs_better_patch: => 0
* severity: Normal => Release blocker
* needs_tests: => 0
* stage: Unreviewed => Accepted


Comment:

I haven't completely verified the report, but bisected the change to
8714403614c4dfa37e806db4a6708b8a91a827a4.

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

Django

unread,
Dec 16, 2015, 5:26:12 AM12/16/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
---------------------------------+------------------------------------

Reporter: arthru | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.9
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
---------------------------------+------------------------------------

Comment (by claudep):

It would help to know a bit more about the use case, notably because your
test didn't set the `coerce` argument. Could you provide a little more
context, also about the form classes involved?

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

Django

unread,
Dec 16, 2015, 8:47:35 AM12/16/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
---------------------------------+------------------------------------

Reporter: arthru | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.9
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
---------------------------------+------------------------------------

Comment (by arthru):

In fact, in my case, the coerce is used using the field's to_python method
as following (my mistake, sorry) :

{{{
from django.db import models
from django.forms import TypedChoiceField

CHOICES = [
('choice1', 'Choice 1'),
('choice2', 'Choice 2'),
('choice3', 'Choice 3')
]

my_choices = models.CharField(
max_length=7,
choices=CHOICES,
null=True,
blank=True,
default=None,
)


kwargs = {
'label': 'Method',
'choices': [
('', '---------'),
('choice1', 'Choice 1'),
('choice2', 'Choice 2'),
('choice3', 'Choice 3')
],
'initial': None,
'empty_value': None,
'required': False,
'help_text': '',
'coerce': my_choices.to_python,
}

tcf = TypedChoiceField(**kwargs)
# the following line did work in django 1.8
assert not tcf.has_changed(None, '')
}}}

Overall, I detected that when using my model in a formset having an
extra=1. When submitting without touching anything, the form is treated as
a changed form due to this changed field (where it should be ignored as
nothing was changed).

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

Django

unread,
Dec 16, 2015, 5:37:44 PM12/16/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
---------------------------------+------------------------------------

Reporter: arthru | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.9
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
---------------------------------+------------------------------------
Changes (by claudep):

* has_patch: 0 => 1


Comment:

That's an issue with `CharField` and `null=True` (which is discouraged).
However, I think the [https://github.com/django/django/pull/5833 PR] fixes
this.

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

Django

unread,
Dec 17, 2015, 2:59:48 AM12/17/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
---------------------------------+------------------------------------

Reporter: arthru | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.9
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
---------------------------------+------------------------------------

Comment (by arthru):

I can confirm that the PR fixes the bug on my code. Thanks for that !

--
Ticket URL: <https://code.djangoproject.com/ticket/25942#comment:5>

Django

unread,
Dec 17, 2015, 9:14:30 AM12/17/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
-------------------------------------+-------------------------------------

Reporter: arthru | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.9
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Ready for
| checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/25942#comment:6>

Django

unread,
Dec 17, 2015, 9:39:03 AM12/17/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
-------------------------------------+-------------------------------------
Reporter: arthru | Owner: nobody
Type: Bug | Status: closed
Component: Forms | Version: 1.9
Severity: Release blocker | Resolution: fixed

Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Claude Paroz <claude@…>):

* status: new => closed
* resolution: => fixed


Comment:

In [changeset:"d91cc25a2a43cb2526943dc2285ffe59e38fabfd" d91cc25]:
{{{
#!CommitTicketReference repository=""
revision="d91cc25a2a43cb2526943dc2285ffe59e38fabfd"
Fixed #25942 -- Fixed TypedChoiceField.has_changed with nullable field

This fixes a regression introduced by 871440361.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25942#comment:7>

Django

unread,
Dec 17, 2015, 9:40:13 AM12/17/15
to django-...@googlegroups.com
#25942: TypedChoiceField.has_changed behaviour has changed between 1.8 and 1.9
-------------------------------------+-------------------------------------
Reporter: arthru | Owner: nobody
Type: Bug | Status: closed
Component: Forms | Version: 1.9

Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Claude Paroz <claude@…>):

In [changeset:"ff077cd6496b6f82195e2dc040f70e19e7c206c9" ff077cd]:
{{{
#!CommitTicketReference repository=""
revision="ff077cd6496b6f82195e2dc040f70e19e7c206c9"
[1.9.x] Fixed #25942 -- Fixed TypedChoiceField.has_changed with nullable
field

This fixes a regression introduced by 871440361.

Backport of d91cc25a2a from master.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25942#comment:8>

Reply all
Reply to author
Forward
0 new messages