fixtures.txt 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. .. _fixtures-explanation:
  2. ========
  3. Fixtures
  4. ========
  5. .. seealso::
  6. * :doc:`/howto/initial-data`
  7. What is a fixture?
  8. ==================
  9. A *fixture* is a collection of files that contain the serialized contents of
  10. the database. Each fixture has a unique name, and the files that comprise the
  11. fixture can be distributed over multiple directories, in multiple applications.
  12. How to produce a fixture?
  13. =========================
  14. Fixtures can be generated by :djadmin:`manage.py dumpdata <dumpdata>`. It's
  15. also possible to generate custom fixtures by directly using :doc:`serialization
  16. tools </topics/serialization>` or even by handwriting them.
  17. How to use a fixture?
  18. =====================
  19. Fixtures can be used to pre-populate database with data for
  20. :ref:`tests <topics-testing-fixtures>`:
  21. .. code-block:: python
  22. class MyTestCase(TestCase):
  23. fixtures = ["fixture-label"]
  24. or to provide some :ref:`initial data <initial-data-via-fixtures>` using the
  25. :djadmin:`loaddata` command:
  26. .. code-block:: shell
  27. django-admin loaddata <fixture label>
  28. Where Django looks for fixtures?
  29. ================================
  30. Django will search in these locations for fixtures:
  31. 1. In the ``fixtures`` directory of every installed application
  32. 2. In any directory listed in the :setting:`FIXTURE_DIRS` setting
  33. 3. In the literal path named by the fixture
  34. Django will load any and all fixtures it finds in these locations that match
  35. the provided fixture names. If the named fixture has a file extension, only
  36. fixtures of that type will be loaded. For example:
  37. .. code-block:: shell
  38. django-admin loaddata mydata.json
  39. would only load JSON fixtures called ``mydata``. The fixture extension must
  40. correspond to the registered name of a
  41. :ref:`serializer <serialization-formats>` (e.g., ``json`` or ``xml``).
  42. If you omit the extensions, Django will search all available fixture types for
  43. a matching fixture. For example:
  44. .. code-block:: shell
  45. django-admin loaddata mydata
  46. would look for any fixture of any fixture type called ``mydata``. If a fixture
  47. directory contained ``mydata.json``, that fixture would be loaded as a JSON
  48. fixture.
  49. The fixtures that are named can include directory components. These directories
  50. will be included in the search path. For example:
  51. .. code-block:: shell
  52. django-admin loaddata foo/bar/mydata.json
  53. would search ``<app_label>/fixtures/foo/bar/mydata.json`` for each installed
  54. application, ``<dirname>/foo/bar/mydata.json`` for each directory in
  55. :setting:`FIXTURE_DIRS`, and the literal path ``foo/bar/mydata.json``.
  56. Fixtures loading order
  57. ----------------------
  58. Multiple fixtures can be specified in the same invocation. For example:
  59. .. code-block:: shell
  60. django-admin loaddata mammals birds insects
  61. or in a test case class:
  62. .. code-block:: python
  63. class AnimalTestCase(TestCase):
  64. fixtures = ["mammals", "birds", "insects"]
  65. The order in which fixtures are loaded follows the order in which they are
  66. listed, whether it's when using the management command or when listing them in
  67. the test case class as shown above.
  68. In these examples, all the fixtures named ``mammals`` from all applications (in
  69. the order in which applications are defined in :setting:`INSTALLED_APPS`) will
  70. be loaded first. Subsequently, all the ``birds`` fixtures will be loaded,
  71. followed by all the ``insects`` fixtures.
  72. Be aware that if the database backend supports row-level constraints, these
  73. constraints will be checked at the end of the transaction. Any relationships
  74. across fixtures may result in a load error if the database configuration does
  75. not support deferred constraint checking (refer to the `MySQL`_ docs for an
  76. example).
  77. .. _MySQL: https://dev.mysql.com/doc/refman/en/constraint-foreign-key.html
  78. How fixtures are saved to the database?
  79. =======================================
  80. When fixture files are processed, the data is saved to the database as is.
  81. Model defined :meth:`~django.db.models.Model.save` methods are not called, and
  82. any :data:`~django.db.models.signals.pre_save` or
  83. :data:`~django.db.models.signals.post_save` signals will be called with
  84. ``raw=True`` since the instance only contains attributes that are local to the
  85. model. You may, for example, want to disable handlers that access
  86. related fields that aren't present during fixture loading and would otherwise
  87. raise an exception::
  88. from django.db.models.signals import post_save
  89. from .models import MyModel
  90. def my_handler(**kwargs):
  91. # disable the handler during fixture loading
  92. if kwargs["raw"]:
  93. return
  94. ...
  95. post_save.connect(my_handler, sender=MyModel)
  96. You could also write a decorator to encapsulate this logic::
  97. from functools import wraps
  98. def disable_for_loaddata(signal_handler):
  99. """
  100. Decorator that turns off signal handlers when loading fixture data.
  101. """
  102. @wraps(signal_handler)
  103. def wrapper(*args, **kwargs):
  104. if kwargs["raw"]:
  105. return
  106. signal_handler(*args, **kwargs)
  107. return wrapper
  108. @disable_for_loaddata
  109. def my_handler(**kwargs): ...
  110. Just be aware that this logic will disable the signals whenever fixtures are
  111. deserialized, not just during :djadmin:`loaddata`.
  112. Compressed fixtures
  113. ===================
  114. Fixtures may be compressed in ``zip``, ``gz``, ``bz2``, ``lzma``, or ``xz``
  115. format. For example:
  116. .. code-block:: shell
  117. django-admin loaddata mydata.json
  118. would look for any of ``mydata.json``, ``mydata.json.zip``, ``mydata.json.gz``,
  119. ``mydata.json.bz2``, ``mydata.json.lzma``, or ``mydata.json.xz``. The first
  120. file contained within a compressed archive is used.
  121. Note that if two fixtures with the same name but different fixture type are
  122. discovered (for example, if ``mydata.json`` and ``mydata.xml.gz`` were found in
  123. the same fixture directory), fixture installation will be aborted, and any data
  124. installed in the call to :djadmin:`loaddata` will be removed from the database.
  125. .. admonition:: MySQL with MyISAM and fixtures
  126. The MyISAM storage engine of MySQL doesn't support transactions or
  127. constraints, so if you use MyISAM, you won't get validation of fixture
  128. data, or a rollback if multiple transaction files are found.
  129. Database-specific fixtures
  130. ==========================
  131. If you're in a multi-database setup, you might have fixture data that
  132. you want to load onto one database, but not onto another. In this
  133. situation, you can add a database identifier into the names of your fixtures.
  134. For example, if your :setting:`DATABASES` setting has a ``users`` database
  135. defined, name the fixture ``mydata.users.json`` or
  136. ``mydata.users.json.gz`` and the fixture will only be loaded when you
  137. specify you want to load data into the ``users`` database.