Fixed #13252 -- Added ability to serialize with natural primary keys.

Added ``--natural-foreign`` and ``--natural-primary`` options and
deprecated the ``--natural`` option to the ``dumpdata`` management
command.

Added ``use_natural_foreign_keys`` and ``use_natural_primary_keys``
arguments and deprecated the ``use_natural_keys`` argument to
``django.core.serializers.Serializer.serialize()``.

Thanks SmileyChris for the suggestion.
This commit is contained in:
Tai Lee 2012-08-01 11:49:01 +10:00 committed by Tim Graham
parent 945e033a69
commit e527c0b6d8
12 changed files with 211 additions and 50 deletions

View file

@ -404,6 +404,12 @@ into the primary key of an actual ``Person`` object.
fields will be effectively unique, you can still use those fields
as a natural key.
.. versionadded:: 1.7
Deserialization of objects with no primary key will always check whether the
model's manager has a ``get_by_natural_key()`` method and if so, use it to
populate the deserialized object's primary key.
Serialization of natural keys
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -426,17 +432,39 @@ Firstly, you need to add another method -- this time to the model itself::
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()``, you provide ``use_natural_foreign_keys=True``
or ``use_natural_primary_keys=True`` arguments::
>>> serializers.serialize('json', [book1, book2], indent=2, use_natural_keys=True)
>>> serializers.serialize('json', [book1, book2], indent=2,
... use_natural_foreign_keys=True, use_natural_primary_keys=True)
When ``use_natural_keys=True`` is specified, Django will use the
``natural_key()`` method to serialize any reference to objects of the
type that defines the method.
When ``use_natural_foreign_keys=True`` is specified, Django will use the
``natural_key()`` method to serialize any foreign key reference to objects
of the type that defines the method.
If you are using :djadmin:`dumpdata` to generate serialized data, you
use the :djadminopt:`--natural` command line flag to generate natural keys.
When ``use_natural_primary_keys=True`` is specified, Django will not provide the
primary key in the serialized data of this object since it can be calculated
during deserialization::
...
{
"model": "store.person",
"fields": {
"first_name": "Douglas",
"last_name": "Adams",
"birth_date": "1952-03-11",
}
}
...
This can be useful when you need to load serialized data into an existing
database and you cannot guarantee that the serialized primary key value is not
already in use, and do not need to ensure that deserialized objects retain the
same primary keys.
If you are using :djadmin:`dumpdata` to generate serialized data, use the
:djadminopt:`--natural-foreign` and :djadminopt:`--natural-primary` command
line flags to generate natural keys.
.. note::
@ -450,6 +478,19 @@ use the :djadminopt:`--natural` command line flag to generate natural keys.
natural keys during serialization, but *not* be able to load those
key values, just don't define the ``get_by_natural_key()`` method.
.. versionchanged:: 1.7
Previously there was only a ``use_natural_keys`` argument for
``serializers.serialize()`` and the `-n` or `--natural` command line flags.
These have been deprecated in favor of the ``use_natural_foreign_keys`` and
``use_natural_primary_keys`` arguments and the corresponding
:djadminopt:`--natural-foreign` and :djadminopt:`--natural-primary` options
for :djadmin:`dumpdata`.
The original argument and command line flags remain for backwards
compatibility and map to the new ``use_natural_foreign_keys`` argument and
`--natural-foreign` command line flag. They'll be removed in Django 1.9.
Dependencies during serialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -459,7 +500,7 @@ a "forward reference" with natural keys -- the data you're referencing
must exist before you include a natural key reference to that data.
To accommodate this limitation, calls to :djadmin:`dumpdata` that use
the :djadminopt:`--natural` option will serialize any model with a
the :djadminopt:`--natural-foreign` option will serialize any model with a
``natural_key()`` method before serializing standard primary key objects.
However, this may not always be enough. If your natural key refers to