Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-mm committed Oct 27, 2023
2 parents 2e2cdf6 + 8d9c0e4 commit c44200d
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 37 deletions.
2 changes: 2 additions & 0 deletions docs/ref/checks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,8 @@ fields:
changed to* ``fields.E010`` *in Django 3.1*.
* **postgres.W004**: Base field for array has warnings: ...

.. _sites-system-checks:

``sites``
---------

Expand Down
3 changes: 1 addition & 2 deletions docs/ref/contrib/gis/geos.txt
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,7 @@ Properties
is simple if and only if it does not intersect itself (except at boundary
points). For example, a :class:`LineString` object is not simple if it
intersects itself. Thus, :class:`LinearRing` and :class:`Polygon` objects
are always simple because they do cannot intersect themselves, by
definition.
are always simple because they cannot intersect themselves, by definition.

.. attribute:: GEOSGeometry.valid

Expand Down
64 changes: 64 additions & 0 deletions docs/topics/checks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,67 @@ Messages are comparable. That allows you to easily write tests::
)
]
self.assertEqual(errors, expected_errors)

Writing integration tests
~~~~~~~~~~~~~~~~~~~~~~~~~

Given the need to register certain checks when the application loads, it can be
useful to test their integration within the system checks framework. This can
be accomplished by using the :func:`~django.core.management.call_command`
function.

For example, this test demonstrates that the :setting:`SITE_ID` setting must be
an integer, a built-in :ref:`check from the sites framework
<sites-system-checks>`::

from django.core.management import call_command
from django.core.management.base import SystemCheckError
from django.test import SimpleTestCase, modify_settings, override_settings


class SystemCheckIntegrationTest(SimpleTestCase):
@override_settings(SITE_ID="non_integer")
@modify_settings(INSTALLED_APPS={"prepend": "django.contrib.sites"})
def test_non_integer_site_id(self):
message = "(sites.E101) The SITE_ID setting must be an integer."
with self.assertRaisesMessage(SystemCheckError, message):
call_command("check")

Consider the following check which issues a warning on deployment if a custom
setting named ``ENABLE_ANALYTICS`` is not set to ``True``::

from django.conf import settings
from django.core.checks import Warning, register


@register("myapp", deploy=True)
def check_enable_analytics_is_true_on_deploy(app_configs, **kwargs):
errors = []
if getattr(settings, "ENABLE_ANALYTICS", None) is not True:
errors.append(
Warning(
"The ENABLE_ANALYTICS setting should be set to True in deployment.",
id="myapp.W001",
)
)
return errors

Given that this check will not raise a ``SystemCheckError``, the presence of
the warning message in the ``stderr`` output can be asserted like so::

from io import StringIO

from django.core.management import call_command
from django.test import SimpleTestCase, override_settings


class EnableAnalyticsDeploymentCheckTest(SimpleTestCase):
@override_settings(ENABLE_ANALYTICS=None)
def test_when_set_to_none(self):
stderr = StringIO()
call_command("check", "-t", "myapp", "--deploy", stderr=stderr)
message = (
"(myapp.W001) The ENABLE_ANALYTICS setting should be set "
"to True in deployment."
)
self.assertIn(message, stderr.getvalue())
103 changes: 69 additions & 34 deletions docs/topics/db/fixtures.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,62 +19,104 @@ How to produce a fixture?
=========================

Fixtures can be generated by :djadmin:`manage.py dumpdata <dumpdata>`. It's
also possible to generate custom fixtures by directly using
:doc:`serialization documentation </topics/serialization>` tools or even by
handwriting them.
also possible to generate custom fixtures by directly using :doc:`serialization
tools </topics/serialization>` or even by handwriting them.

What to use a fixture for?
==========================
How to use a fixture?
=====================

Fixtures can be used to pre-populate database with data for
:ref:`tests <topics-testing-fixtures>` or to provide some :ref:`initial data
<initial-data-via-fixtures>`.
:ref:`tests <topics-testing-fixtures>`:

.. code-block:: python

class MyTestCase(TestCase):
fixtures = ["fixture-label"]

or to provide some :ref:`initial data <initial-data-via-fixtures>` using the
:djadmin:`loaddata` command:

.. code-block:: shell

django-admin loaddata <fixture label>


Where Django looks for fixtures?
================================

Django will search in three locations for fixtures:
Django will search in these locations for fixtures:

1. In the ``fixtures`` directory of every installed application
2. In any directory named in the :setting:`FIXTURE_DIRS` setting
2. In any directory listed in the :setting:`FIXTURE_DIRS` setting
3. In the literal path named by the fixture

Django will load any and all fixtures it finds in these locations that match
the provided fixture names.

If the named fixture has a file extension, only fixtures of that type
will be loaded. For example:
the provided fixture names. If the named fixture has a file extension, only
fixtures of that type will be loaded. For example:

.. code-block:: shell

django-admin loaddata mydata.json

would only load JSON fixtures called ``mydata``. The fixture extension
must correspond to the registered name of a
would only load JSON fixtures called ``mydata``. The fixture extension must
correspond to the registered name of a
:ref:`serializer <serialization-formats>` (e.g., ``json`` or ``xml``).

If you omit the extensions, Django will search all available fixture types
for a matching fixture. For example:
If you omit the extensions, Django will search all available fixture types for
a matching fixture. For example:

.. code-block:: shell

django-admin loaddata mydata

would look for any fixture of any fixture type called ``mydata``. If a fixture
directory contained ``mydata.json``, that fixture would be loaded
as a JSON fixture.
directory contained ``mydata.json``, that fixture would be loaded as a JSON
fixture.

The fixtures that are named can include directory components. These
directories will be included in the search path. For example:
The fixtures that are named can include directory components. These directories
will be included in the search path. For example:

.. code-block:: shell

django-admin loaddata foo/bar/mydata.json

would search ``<app_label>/fixtures/foo/bar/mydata.json`` for each installed
application, ``<dirname>/foo/bar/mydata.json`` for each directory in
application, ``<dirname>/foo/bar/mydata.json`` for each directory in
:setting:`FIXTURE_DIRS`, and the literal path ``foo/bar/mydata.json``.

Fixtures loading order
----------------------

Multiple fixtures can be specified in the same invocation. For example:

.. code-block:: shell

manage.py loaddata mammals birds insects

or in a test case class:

.. code-block:: python

class AnimalTestCase(TestCase):
fixtures = ["mammals", "birds", "insects"]

The order in which fixtures are loaded follows the order in which they are
listed, whether it's when using the management command or when listing them in
the test case class as shown above.

In these examples, all the fixtures named ``mammals`` from all applications (in
the order in which applications are defined in :setting:`INSTALLED_APPS`) will
be loaded first. Subsequently, all the ``birds`` fixtures will be loaded,
followed by all the ``insects`` fixtures.

Be aware that if the database backend supports row-level constraints, these
constraints will be checked at the end of the transaction. Any relationships
across fixtures may result in a load error if the database configuration does
not support deferred constraint checking (refer to the `MySQL`_ docs for an
example).

.. _MySQL: https://dev.mysql.com/doc/refman/en/constraint-foreign-key.html

How fixtures are saved to the database?
=======================================

Expand Down Expand Up @@ -124,13 +166,7 @@ You could also write a decorator to encapsulate this logic::
...

Just be aware that this logic will disable the signals whenever fixtures are
deserialized, not just during ``loaddata``.

Note that the order in which fixture files are processed is undefined. However,
all fixture data is installed as a single transaction, so data in
one fixture can reference data in another fixture. If the database backend
supports row-level constraints, these constraints will be checked at the
end of the transaction.
deserialized, not just during :djadmin:`loaddata`.

Compressed fixtures
===================
Expand All @@ -146,11 +182,10 @@ would look for any of ``mydata.json``, ``mydata.json.zip``, ``mydata.json.gz``,
``mydata.json.bz2``, ``mydata.json.lzma``, or ``mydata.json.xz``. The first
file contained within a compressed archive is used.

Note that if two fixtures with the same name but different
fixture type are discovered (for example, if ``mydata.json`` and
``mydata.xml.gz`` were found in the same fixture directory), fixture
installation will be aborted, and any data installed in the call to
``loaddata`` will be removed from the database.
Note that if two fixtures with the same name but different fixture type are
discovered (for example, if ``mydata.json`` and ``mydata.xml.gz`` were found in
the same fixture directory), fixture installation will be aborted, and any data
installed in the call to :djadmin:`loaddata` will be removed from the database.

.. admonition:: MySQL with MyISAM and fixtures

Expand Down
2 changes: 1 addition & 1 deletion tests/backends/base/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_check_database_version_supported_with_none_as_database_version(self):


class DatabaseWrapperLoggingTests(TransactionTestCase):
available_apps = []
available_apps = ["backends"]

@override_settings(DEBUG=True)
def test_commit_debug_log(self):
Expand Down

0 comments on commit c44200d

Please sign in to comment.