Commit 5a2324af authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

Fixed #13418 -- Added notes on uniqueness requirements for natural keys....

Fixed #13418 -- Added notes on uniqueness requirements for natural keys. Thanks to hunajakippo for the suggestion, and Ramiro Morales for the draft text.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13146 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent e7e46d1f
Loading
Loading
Loading
Loading
+29 −6
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ Natural keys
------------

.. versionadded:: 1.2

   The ability to use natural keys when serializing/deserializing data was
   added in the 1.2 release.

@@ -219,13 +220,13 @@ There is also the matter of convenience. An integer id isn't always
the most convenient way to refer to an object; sometimes, a
more natural reference would be helpful.

Deserialization of natural keys
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It is for these reasons that Django provides `natural keys`. A natural
It is for these reasons that Django provides *natural keys*. A natural
key is a tuple of values that can be used to uniquely identify an
object instance without using the primary key value.

Deserialization of natural keys
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Consider the following two models::

    from django.db import models
@@ -236,6 +237,9 @@ Consider the following two models::

        birthdate = models.DateField()

        class Meta:
            unique_together = (('first_name', 'last_name'),)

    class Book(models.Model):
        name = models.CharField(max_length=100)
        author = models.ForeignKey(Person)
@@ -278,6 +282,9 @@ name::

        birthdate = models.DateField()

        class Meta:
            unique_together = (('first_name', 'last_name'),)

Now books can use that natural key to refer to ``Person`` objects::

    ...
@@ -295,6 +302,17 @@ When you try to load this serialized data, Django will use the
``get_by_natural_key()`` method to resolve ``["Douglas", "Adams"]``
into the primary key of an actual ``Person`` object.

.. note::

    Whatever fields you use for a natural key must be able to uniquely
    identify an object. This will usually mean that your model will
    have a uniqueness clause (either unique=True on a single field, or
    ``unique_together`` over multiple fields) for the field or fields
    in your natural key. However, uniqueness doesn't need to be
    enforced at the database level. If you are certain that a set of
    fields will be effectively unique, you can still use those fields
    as a natural key.

Serialization of natural keys
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

@@ -312,8 +330,13 @@ Firstly, you need to add another method -- this time to the model itself::
        def natural_key(self):
            return (self.first_name, self.last_name)

Then, when you call ``serializers.serialize()``, you provide a
``use_natural_keys=True`` argument::
        class Meta:
            unique_together = (('first_name', 'last_name'),)

That method should always return a natural key tuple -- in this
example, ``(first name, last name)``. Then, when you call
``serializers.serialize()``, you provide a ``use_natural_keys=True``
argument::

    >>> serializers.serialize([book1, book2], format='json', indent=2, use_natural_keys=True)