[Django] #28742: get/set on a OneToOneField produces AttributeError

7 views
Skip to first unread message

Django

unread,
Oct 25, 2017, 9:53:13 AM10/25/17
to django-...@googlegroups.com
#28742: get/set on a OneToOneField produces AttributeError
-------------------------------------+-------------------------------------
Reporter: Faidon | Owner: nobody
Liambotis |
Type: Bug | Status: new
Component: Database | Version: 1.11
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
On a sample empty project (mysite) with a sample empty app (myapp) with
these models:

{{{
from django.db import models

class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)

class Restaurant(models.Model):
place = models.OneToOneField(Place)
serves_hot_dogs = models.BooleanField(default=False)
serves_pizza = models.BooleanField(default=False)
}}}

Executing this, works just fine:
{{{
p = Place()
p.restaurant = None
}}}

But this:
{{{
p = Place()
r = getattr(p, 'restaurant', None)
p.restaurant = None
}}}

…raises an AttributeError:
{{{
AttributeError Traceback (most recent call
last)
<ipython-input-4-c4df23702cac> in <module>()
----> 1 p.restaurant = None

.../lib/python3.5/site-
packages/django/db/models/fields/related_descriptors.py in __set__(self,
instance, value)
435 else:
436 delattr(instance, self.cache_name)
--> 437 setattr(rel_obj, self.related.field.name, None)
438 elif not isinstance(value, self.related.related_model):
439 # An object must be an instance of the related class.

AttributeError: 'NoneType' object has no attribute 'place'
}}}

The above is with Python 3.5.3 and Django 1.11.6, although user "knbk" on
#django said that they reproduced it in master.

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

Django

unread,
Oct 25, 2017, 10:39:51 AM10/25/17
to django-...@googlegroups.com
#28742: get/set on a OneToOneField produces AttributeError
-------------------------------------+-------------------------------------
Reporter: Faidon Liambotis | 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 Tim Graham):

* stage: Unreviewed => Accepted


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

Django

unread,
Oct 28, 2017, 8:48:54 PM10/28/17
to django-...@googlegroups.com
#28742: get/set on a OneToOneField produces AttributeError
-------------------------------------+-------------------------------------
Reporter: Faidon Liambotis | 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 Josh Schneier):

Another way of reproducing this is with

{{{#!python
def test_getattr_getter(self):
place = Place()
try:
place.restaurant
except Restaurant.DoesNotExist:
place.restaurant = None
}}}

The problem is that we are caching the return of
`Restaurant.DoesNotExist`. Removing the caching triggers a regression test
for #17439. I saw that Aymeric closed that one quite a while ago so I'd be
interested on some additional thoughts.

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

Django

unread,
Oct 29, 2017, 6:15:20 AM10/29/17
to django-...@googlegroups.com
#28742: get/set on a OneToOneField produces AttributeError
-------------------------------------+-------------------------------------
Reporter: Faidon Liambotis | Owner: Paulo
Type: Bug | Status: assigned

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 Paulo):

* owner: nobody => Paulo
* status: new => assigned


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

Django

unread,
Oct 29, 2017, 7:03:56 AM10/29/17
to django-...@googlegroups.com
#28742: get/set on a OneToOneField produces AttributeError
-------------------------------------+-------------------------------------
Reporter: Faidon Liambotis | Owner: Paulo
Type: Bug | Status: assigned
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 Paulo):

PR: https://github.com/django/django/pull/9305
I think the regression came from
https://github.com/django/django/commit/384ddbec1b73a4636f234da3894fde8f8420bb63

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

Django

unread,
Oct 30, 2017, 10:41:01 AM10/30/17
to django-...@googlegroups.com
#28742: get/set on a OneToOneField produces AttributeError
-------------------------------------+-------------------------------------
Reporter: Faidon Liambotis | Owner: Paulo
Type: Bug | Status: assigned
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | 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:

The test in the PR is failing as far back as I tested (Django 1.7, note:
you have to update the models according to
7fe554b2a3d72d0142e5c9e97efbd0a672c2d790 there).

Are you seeing a regression from an older version of Django?

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

Django

unread,
Oct 30, 2017, 10:47:25 AM10/30/17
to django-...@googlegroups.com
#28742: get/set on a OneToOneField produces AttributeError
-------------------------------------+-------------------------------------
Reporter: Faidon Liambotis | Owner: Paulo
Type: Bug | Status: assigned
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | 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 Paulo):

I didn't test that far back.
Only traced the AttributeError to the commit above, before that I assume a
ValueError was raised because setting None was just not allowed.
So is not really a regression.

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

Django

unread,
Oct 30, 2017, 2:24:34 PM10/30/17
to django-...@googlegroups.com
#28742: get/set on a OneToOneField produces AttributeError
-------------------------------------+-------------------------------------
Reporter: Faidon Liambotis | Owner: Paulo
Type: Bug | Status: closed

Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution: fixed
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 <timograham@…>):

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


Comment:

In [changeset:"fcfcf8aae470d893b0d2ef176434461edf9e9c4d" fcfcf8a]:
{{{
#!CommitTicketReference repository=""
revision="fcfcf8aae470d893b0d2ef176434461edf9e9c4d"
Fixed #28742 -- Fixed AttributeError crash when assigning None to cached
reverse relations.
}}}

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

Django

unread,
Oct 30, 2017, 2:33:41 PM10/30/17
to django-...@googlegroups.com
#28742: get/set on a OneToOneField produces AttributeError
-------------------------------------+-------------------------------------
Reporter: Faidon Liambotis | Owner: Paulo
Type: Bug | Status: closed
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution: fixed
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 Tim Graham <timograham@…>):

In [changeset:"f2d5417d3b7a4012298fcffc6eab618cc09d0344" f2d5417d]:
{{{
#!CommitTicketReference repository=""
revision="f2d5417d3b7a4012298fcffc6eab618cc09d0344"
[2.0.x] Fixed #28742 -- Fixed AttributeError crash when assigning None to
cached reverse relations.

Backport of fcfcf8aae470d893b0d2ef176434461edf9e9c4d from master
}}}

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

Reply all
Reply to author
Forward
0 new messages