Ticket #16364: 16364_v2.patch

File 16364_v2.patch, 5.6 KB (added by gabrielhurley, 3 years ago)

Second pass at docs

  • docs/topics/serialization.txt

     
    198198------------
    199199
    200200.. versionadded:: 1.2
     201
    201202   The ability to use natural keys when serializing/deserializing data was
    202203   added in the 1.2 release.
    203204
    204 The default serialization strategy for foreign keys and many-to-many
    205 relations is to serialize the value of the primary key(s) of the
    206 objects in the relation. This strategy works well for most types of
    207 object, but it can cause difficulty in some circumstances.
     205The default serialization strategy for foreign keys and many-to-many relations
     206is to serialize the value of the primary key(s) of the objects in the relation.
     207This strategy works well for most objects, but it can cause difficulty in some
     208circumstances.
    208209
    209 Consider the case of a list of objects that have foreign key on
    210 :class:`ContentType`. If you're going to serialize an object that
    211 refers to a content type, you need to have a way to refer to that
    212 content type. Content Types are automatically created by Django as
    213 part of the database synchronization process, so you don't need to
    214 include content types in a fixture or other serialized data. As a
    215 result, the primary key of any given content type isn't easy to
    216 predict - it will depend on how and when :djadmin:`syncdb` was
    217 executed to create the content types.
     210Consider the case of a list of objects that have a foreign key referencing
     211:class:`~django.contrib.conttenttypes.models.ContentType`. If you're going to
     212serialize an object that refers to a content type, then you need to have a way
     213to refer to that content type to begin with. Since ``ContentType`` objects are
     214automatically created by Django during the database synchronization process,
     215the primary key of a given content type isn't easy to predict; it will
     216depend on how and when :djadmin:`syncdb` was executed. This is true for all
     217models which automatically generate objects, notably including
     218:class:`~django.contrib.auth.models.Permission`.
    218219
     220.. warning::
     221
     222    You should never include automatically generated objects in a fixture or
     223    other serialized data. By chance, the primary keys in the fixture
     224    may match those in the database and loading the fixture will
     225    have no effect. In the more likely case that they don't match, the fixture
     226    loading will fail with an :class:`~django.db.IntegrityError`.
     227
    219228There is also the matter of convenience. An integer id isn't always
    220229the most convenient way to refer to an object; sometimes, a
    221230more natural reference would be helpful.
     
    363372~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    364373
    365374Since natural keys rely on database lookups to resolve references, it
    366 is important that data exists before it is referenced. You can't make
    367 a `forward reference` with natural keys - the data you are referencing
     375is important that the data exists before it is referenced. You can't make
     376a `forward reference` with natural keys--the data you are referencing
    368377must exist before you include a natural key reference to that data.
    369378
    370379To accommodate this limitation, calls to :djadmin:`dumpdata` that use
    371380the :djadminopt:`--natural` option will serialize any model with a
    372 ``natural_key()`` method before it serializes normal key objects.
     381``natural_key()`` method before serializing standard primary key objects.
    373382
    374383However, this may not always be enough. If your natural key refers to
    375384another object (by using a foreign key or natural key to another object
     
    381390``natural_key()`` methods. You do this by setting a ``dependencies``
    382391attribute on the ``natural_key()`` method itself.
    383392
    384 For example, consider the ``Permission`` model in ``contrib.auth``.
    385 The following is a simplified version of the ``Permission`` model::
     393For example, let's add a natural key to the ``Book`` model from the
     394example above::
    386395
    387     class Permission(models.Model):
    388         name = models.CharField(max_length=50)
    389         content_type = models.ForeignKey(ContentType)
    390         codename = models.CharField(max_length=100)
    391         # ...
     396    class Book(models.Model):
     397        name = models.CharField(max_length=100)
     398        author = models.ForeignKey(Person)
     399
    392400        def natural_key(self):
    393             return (self.codename,) + self.content_type.natural_key()
     401            return (self.name,) + self.author.natural_key()
    394402
    395 The natural key for a ``Permission`` is a combination of the codename for the
    396 ``Permission``, and the ``ContentType`` to which the ``Permission`` applies. This means
    397 that ``ContentType`` must be serialized before ``Permission``. To define this
    398 dependency, we add one extra line::
     403The natural key for a ``Book`` is a combination of its name and its
     404author.  This means that ``Person`` must be serialized before ``Book``.
     405To define this dependency, we add one extra line::
    399406
    400     class Permission(models.Model):
    401         # ...
    402407        def natural_key(self):
    403             return (self.codename,) + self.content_type.natural_key()
    404         natural_key.dependencies = ['contenttypes.contenttype']
     408            return (self.name,) + self.author.natural_key()
     409        natural_key.dependencies = ['example_app.person']
    405410
    406 This definition ensures that ``ContentType`` models are serialized before
    407 ``Permission`` models. In turn, any object referencing ``Permission`` will
    408 be serialized after both ``ContentType`` and ``Permission``.
     411This definition ensures that all ``Person`` objects are serialized before
     412any ``Book`` objects. In turn, any object referencing ``Book`` will be
     413serialized after both ``Person`` and ``Book`` have been serialized.
Back to Top