Ticket #16364: 16364_v2.patch
File 16364_v2.patch, 5.6 KB (added by , 13 years ago) |
---|
-
docs/topics/serialization.txt
198 198 ------------ 199 199 200 200 .. versionadded:: 1.2 201 201 202 The ability to use natural keys when serializing/deserializing data was 202 203 added in the 1.2 release. 203 204 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 somecircumstances.205 The default serialization strategy for foreign keys and many-to-many relations 206 is to serialize the value of the primary key(s) of the objects in the relation. 207 This strategy works well for most objects, but it can cause difficulty in some 208 circumstances. 208 209 209 Consider the case of a list of objects that have foreign key on210 :class:` ContentType`. If you're going to serialize an object that211 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.210 Consider 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 212 serialize an object that refers to a content type, then you need to have a way 213 to refer to that content type to begin with. Since ``ContentType`` objects are 214 automatically created by Django during the database synchronization process, 215 the primary key of a given content type isn't easy to predict; it will 216 depend on how and when :djadmin:`syncdb` was executed. This is true for all 217 models which automatically generate objects, notably including 218 :class:`~django.contrib.auth.models.Permission`. 218 219 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 219 228 There is also the matter of convenience. An integer id isn't always 220 229 the most convenient way to refer to an object; sometimes, a 221 230 more natural reference would be helpful. … … 363 372 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 364 373 365 374 Since natural keys rely on database lookups to resolve references, it 366 is important that data exists before it is referenced. You can't make367 a `forward reference` with natural keys -the data you are referencing375 is important that the data exists before it is referenced. You can't make 376 a `forward reference` with natural keys--the data you are referencing 368 377 must exist before you include a natural key reference to that data. 369 378 370 379 To accommodate this limitation, calls to :djadmin:`dumpdata` that use 371 380 the :djadminopt:`--natural` option will serialize any model with a 372 ``natural_key()`` method before it serializes normalkey objects.381 ``natural_key()`` method before serializing standard primary key objects. 373 382 374 383 However, this may not always be enough. If your natural key refers to 375 384 another object (by using a foreign key or natural key to another object … … 381 390 ``natural_key()`` methods. You do this by setting a ``dependencies`` 382 391 attribute on the ``natural_key()`` method itself. 383 392 384 For example, consider the ``Permission`` model in ``contrib.auth``.385 The following is a simplified version of the ``Permission`` model::393 For example, let's add a natural key to the ``Book`` model from the 394 example above:: 386 395 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 392 400 def natural_key(self): 393 return (self. codename,) + self.content_type.natural_key()401 return (self.name,) + self.author.natural_key() 394 402 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:: 403 The natural key for a ``Book`` is a combination of its name and its 404 author. This means that ``Person`` must be serialized before ``Book``. 405 To define this dependency, we add one extra line:: 399 406 400 class Permission(models.Model):401 # ...402 407 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'] 405 410 406 This definition ensures that ``ContentType`` models are serialized before407 ``Permission`` models. In turn, any object referencing ``Permission`` will 408 be serialized after both ``ContentType`` and ``Permission``.411 This definition ensures that all ``Person`` objects are serialized before 412 any ``Book`` objects. In turn, any object referencing ``Book`` will be 413 serialized after both ``Person`` and ``Book`` have been serialized.