[Django] #28210: `<orm_object>._state.adding` behaviour and model inheritance

69 views
Skip to first unread message

Django

unread,
May 16, 2017, 3:56:39 AM5/16/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
------------------------------------------+------------------------
Reporter: Ivaylo Donchev | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.11
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------+------------------------
Let's say we have the following models:
{{{
class User(models.Model):
email = models.CharField(max_length=255, unique=True)
password = models.CharField(max_length=32,
widget=forms.PasswordInput)

class Admin(User):
pass

class ThirdPartyUser(User):
pass
}}}

Steps to reproduce:
1. {{{ admin = Admin.objects.create(email='ad...@admin.com') }}}


This will create an Admin instance and User instance, with
`admin.user_ptr._state.adding == True`

2. {{{ ThirdPartyUser.objects.create(user_ptr = admin.user_ptr) }}}


This will raise the following error `{'email': ['User with this Email
address already exists.'], 'id': ['User with this ID already exists.'] }`
When the admin is created, the `admin.user_ptr._state.adding` is True, but
admin._state.adding is False (as it is already created).
If we set {{{ admin.user_ptr._state.adding = False }}}, step 2 is passing
without errors.

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

Django

unread,
May 16, 2017, 9:18:53 AM5/16/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
--------------------------------+--------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.11
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
--------------------------------+--------------------------------------

Comment (by Simon Charette):

This looks similar to #28166 which has been fixed in 1.11.1. Can you
confirm it's the case?

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

Django

unread,
May 17, 2017, 3:30:20 AM5/17/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
--------------------------------+--------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.11
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
--------------------------------+--------------------------------------

Comment (by Ivaylo Donchev):

Yeah, but it's not about the **_state.db**.Basically, if we have these
two models:
{{{
class Parent(models.Model):
pass
class ChildA(Parent):
pass
class ChildB(Parent):
pass

}}}
and we create "ChildA" object with **obj = ChildA.objects.create()**,
we'll have 2 new instances - ***(ChildA) obj*** and ***(Parent)
obj.parent_ptr)***. Now, if you try to create "ChildB" instance as
follows:
{{{
parent = obj.parent_ptr # parent._state.adding == True
child_b = ChildB(parent_ptr=obj.parent_ptr)
child_b.__dict__.update(parent) # to set all required attributes (if
any)
child_b.full_clean() # this will throw an error for all of the unique
fields of the parent instance ("id"for example)
child_b.save()
}}}
So, if you set {{{ obj.parent_ptr._state.adding = False }}} as soon as obj
is created, the code above is working without errors.
Basically, the problem is that if we don't modify the _state's adding,
it's no possible to create a new instance with the same parent_ptr.

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

Django

unread,
May 17, 2017, 10:11:57 AM5/17/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
-------------------------------------+-------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | 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 Simon Charette):

* component: Uncategorized => Database layer (models, ORM)
* type: Uncategorized => Bug
* stage: Unreviewed => Accepted


Comment:

Could you confirm whether or not it's a regression from 1.10? It could be
related to 38575b007a722d6af510ea46d46393a4cda9ca29 as well.

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

Django

unread,
May 18, 2017, 10:29:40 AM5/18/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
-------------------------------------+-------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | 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 Ivaylo Donchev):

Well, I hit this bug while upgrading Django from 1.10 to 1.11.1, but I
didn't reproduce all the corner cases in the Django1.10.
Replying to [comment:3 Simon Charette]:


> Could you confirm whether or not it's a regression from 1.10? It could
be related to 38575b007a722d6af510ea46d46393a4cda9ca29 as well.

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

Django

unread,
May 18, 2017, 12:45:10 PM5/18/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
-------------------------------------+-------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
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 Simon Charette):

* cc: Simon Charette (added)
* severity: Normal => Release blocker


Comment:

Tentatively escalating as a release blocker as everything seems to
indicate this is a regression.

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

Django

unread,
May 19, 2017, 8:38:55 AM5/19/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
-------------------------------------+-------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
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
-------------------------------------+-------------------------------------

Old description:

> Let's say we have the following models:
> {{{
> class User(models.Model):
> email = models.CharField(max_length=255, unique=True)
> password = models.CharField(max_length=32,
> widget=forms.PasswordInput)
>
> class Admin(User):
> pass
>
> class ThirdPartyUser(User):
> pass
> }}}
>
> Steps to reproduce:
> 1. {{{ admin = Admin.objects.create(email='ad...@admin.com') }}}
>

> This will create an Admin instance and User instance, with
> `admin.user_ptr._state.adding == True`
>
> 2. {{{ ThirdPartyUser.objects.create(user_ptr = admin.user_ptr) }}}
>

> This will raise the following error `{'email': ['User with this Email
> address already exists.'], 'id': ['User with this ID already exists.'] }`
> When the admin is created, the `admin.user_ptr._state.adding` is True,
> but admin._state.adding is False (as it is already created).
> If we set {{{ admin.user_ptr._state.adding = False }}}, step 2 is passing
> without errors.

New description:

Let's say we have the following models:
{{{
class User(models.Model):
email = models.CharField(max_length=255, unique=True)

password = models.CharField(max_length=32)

class Admin(User):
pass

class ThirdPartyUser(User):
pass
}}}

Steps to reproduce:
1. {{{ admin = Admin.objects.create(email='ad...@admin.com') }}}


This will create an Admin instance and User instance, with
`admin.user_ptr._state.adding == True`

2. {{{ ThirdPartyUser.objects.create(user_ptr = admin.user_ptr) }}}


This will raise the following error `{'email': ['User with this Email
address already exists.'], 'id': ['User with this ID already exists.'] }`
When the admin is created, the `admin.user_ptr._state.adding` is True, but
admin._state.adding is False (as it is already created).
If we set {{{ admin.user_ptr._state.adding = False }}}, step 2 is passing
without errors.

--

Comment (by Tim Graham):

I can't reproduce using the steps described in the description. How does
`ThirdPartyUser.objects.create()` raise a dictionary? Please clarify.

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

Django

unread,
May 19, 2017, 10:14:53 AM5/19/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
-------------------------------------+-------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
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 Simon Charette):

Tim, I think the reporter was referring to form validation generating a
`form.errors` along the dict he provided.

Unique field validation relies on the `_state.adding` flag to determine
[https://github.com/django/django/blob/master/django/db/models/base.py#L1013
whether or not it should run].

An appropriate test in this case would be along the lines of

{{{#!python
child = Child.objects.create()
self.assertFalse(child.parent_ptr._state.adding)
}}}

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

Django

unread,
May 19, 2017, 1:13:29 PM5/19/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
-------------------------------------+-------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
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 Tim Graham):

* has_patch: 0 => 1


Comment:

[https://github.com/django/django/pull/8519 PR]

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

Django

unread,
May 19, 2017, 2:10:17 PM5/19/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
-------------------------------------+-------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
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 Simon Charette):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/28210#comment:9>

Django

unread,
May 19, 2017, 9:09:55 PM5/19/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
-------------------------------------+-------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Bug | Status: closed

Component: Database layer | Version: 1.11
(models, ORM) |
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 Tim Graham <timograham@…>):

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


Comment:

In [changeset:"59ab1b2683b6c090dc409d9eb8303aadbd590c04" 59ab1b26]:
{{{
#!CommitTicketReference repository=""
revision="59ab1b2683b6c090dc409d9eb8303aadbd590c04"
Fixed #28210 -- Fixed Model._state.adding on MTI parent model after saving
child model.

Regression in 38575b007a722d6af510ea46d46393a4cda9ca29.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/28210#comment:10>

Django

unread,
May 19, 2017, 9:31:20 PM5/19/17
to django-...@googlegroups.com
#28210: `<orm_object>._state.adding` behaviour and model inheritance
-------------------------------------+-------------------------------------

Reporter: Ivaylo Donchev | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 1.11
(models, ORM) |
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 Tim Graham <timograham@…>):

In [changeset:"f2b8fa1763116a9b8fbe7791a4b009c95cf8c0b1" f2b8fa17]:
{{{
#!CommitTicketReference repository=""
revision="f2b8fa1763116a9b8fbe7791a4b009c95cf8c0b1"
[1.11.x] Fixed #28210 -- Fixed Model._state.adding on MTI parent model
after saving child model.

Regression in 38575b007a722d6af510ea46d46393a4cda9ca29.

Backport of 59ab1b2683b6c090dc409d9eb8303aadbd590c04 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/28210#comment:11>

Reply all
Reply to author
Forward
0 new messages