summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/releases/1.8.txt52
-rw-r--r--docs/topics/db/examples/many_to_one.txt15
-rw-r--r--docs/topics/db/examples/one_to_one.txt19
3 files changed, 74 insertions, 12 deletions
diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt
index 087098b4ba..31f4fb2cbb 100644
--- a/docs/releases/1.8.txt
+++ b/docs/releases/1.8.txt
@@ -218,19 +218,47 @@ Backwards incompatible changes in 1.8
deprecation timeline for a given feature, its removal may appear as a
backwards incompatible change.
-* Some operations on related objects such as
- :meth:`~django.db.models.fields.related.RelatedManager.add()` or
- :ref:`direct assignment<direct-assignment>` ran multiple data modifying
- queries without wrapping them in transactions. To reduce the risk of data
- corruption, all data modifying methods that affect multiple related objects
- (i.e. ``add()``, ``remove()``, ``clear()``, and
- :ref:`direct assignment<direct-assignment>`) now perform their data modifying
- queries from within a transaction, provided your database supports
- transactions.
+Related object operations are run in a transaction
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- This has one backwards incompatible side effect, signal handlers triggered
- from these methods are now executed within the method's transaction and
- any exception in a signal handler will prevent the whole operation.
+Some operations on related objects such as
+:meth:`~django.db.models.fields.related.RelatedManager.add()` or
+:ref:`direct assignment<direct-assignment>` ran multiple data modifying
+queries without wrapping them in transactions. To reduce the risk of data
+corruption, all data modifying methods that affect multiple related objects
+(i.e. ``add()``, ``remove()``, ``clear()``, and :ref:`direct assignment
+<direct-assignment>`) now perform their data modifying queries from within a
+transaction, provided your database supports transactions.
+
+This has one backwards incompatible side effect, signal handlers triggered from
+these methods are now executed within the method's transaction and any
+exception in a signal handler will prevent the whole operation.
+
+Unassigning unsaved objects to relations raises an error
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Assigning unsaved objects to a :class:`~django.db.models.ForeignKey`,
+:class:`~django.contrib.contenttypes.fields.GenericForeignKey`, and
+:class:`~django.db.models.OneToOneField` now raises a :exc:`ValueError`.
+
+Previously, the assignment of an unsaved object would be silently ignored.
+For example::
+
+ >>> book = Book.objects.create(name="Django")
+ >>> book.author = Author(name="John")
+ >>> book.author.save()
+ >>> book.save()
+
+ >>> Book.objects.get(name="Django")
+ >>> book.author
+ >>>
+
+Now, an error will be raised to prevent data loss::
+
+ >>> book.author = Author(name="john")
+ Traceback (most recent call last):
+ ...
+ ValueError: Cannot assign "<Author: John>": "Author" instance isn't saved in the database.
Miscellaneous
~~~~~~~~~~~~~
diff --git a/docs/topics/db/examples/many_to_one.txt b/docs/topics/db/examples/many_to_one.txt
index 1101865755..7de8e6f51f 100644
--- a/docs/topics/db/examples/many_to_one.txt
+++ b/docs/topics/db/examples/many_to_one.txt
@@ -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
diff --git a/docs/topics/db/examples/one_to_one.txt b/docs/topics/db/examples/one_to_one.txt
index b66d52d369..beb4aa01d9 100644
--- a/docs/topics/db/examples/one_to_one.txt
+++ b/docs/topics/db/examples/one_to_one.txt
@@ -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::