Fixed #10811 -- Made assigning unsaved objects to FK, O2O, and GFK raise ValueError.

This prevents silent data loss.

Thanks Aymeric Augustin for the initial patch and Loic Bistuer for the review.
This commit is contained in:
Anubhav Joshi 2014-05-19 14:15:55 +05:30 committed by Tim Graham
parent 4f72e5f03a
commit 5643a3b51b
12 changed files with 141 additions and 76 deletions

View file

@ -52,6 +52,21 @@ Create an Article::
>>> a.reporter
<Reporter: John Smith>
Note that you must save an object before it can be assigned to a foreign key
relationship. For example, creating an ``Article`` with unsaved ``Reporter``
raises ``ValueError``::
>>> r3 = Reporter(first_name='John', last_name='Smith', email='john@example.com')
>>> Article(headline="This is a test", pub_date=date(2005, 7, 27), reporter=r3)
Traceback (most recent call last):
...
ValueError: 'Cannot assign "<Reporter: John Smith>": "Reporter" instance isn't saved in the database.'
.. versionchanged:: 1.8
Previously, assigning unsaved objects did not raise an error and could
result in silent data loss.
Article objects have access to their related Reporter objects::
>>> r = a.reporter

View file

@ -89,6 +89,25 @@ Set the place back again, using assignment in the reverse direction::
>>> p1.restaurant
<Restaurant: Demon Dogs the restaurant>
Note that you must save an object before it can be assigned to a one-to-one
relationship. For example, creating an ``Restaurant`` with unsaved ``Place``
raises ``ValueError``::
>>> p3 = Place(name='Demon Dogs', address='944 W. Fullerton')
>>> Restaurant(place=p3, serves_hot_dogs=True, serves_pizza=False)
Traceback (most recent call last):
...
ValueError: 'Cannot assign "<Place: Demon Dogs>": "Place" instance isn't saved in the database.'
>>> p.restaurant = Restaurant(place=p, serves_hot_dogs=True, serves_pizza=False)
Traceback (most recent call last):
...
ValueError: 'Cannot assign "<Restaurant: Demon Dogs the restaurant>": "Restaurant" instance isn't saved in the database.'
.. versionchanged:: 1.8
Previously, assigning unsaved objects did not raise an error and could
result in silent data loss.
Restaurant.objects.all() just returns the Restaurants, not the Places. Note
that there are two restaurants - Ace Hardware the Restaurant was created in the
call to r.place = p2::