diff --git a/pytest_django/fixtures.py b/pytest_django/fixtures.py index 7fcfe679..788b2f24 100644 --- a/pytest_django/fixtures.py +++ b/pytest_django/fixtures.py @@ -431,10 +431,16 @@ def finalize(self) -> None: @pytest.fixture() -def settings(): +def settings(request): """A Django settings object which restores changes after the testrun""" skip_if_no_django() + # Order the `settings` fixture after DB. + # We don't want overridden settings to be in effect during + # DB setup/teardown/post_migrate. + if 'transactional_db' in request.fixturenames: + request.getfixturevalue('transactional_db') + wrapper = SettingsWrapper() yield wrapper wrapper.finalize() diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 427c6c8a..b1958d57 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -408,6 +408,30 @@ def test_set_non_existent(settings): ] ) + def test_transactional_db_order(self, django_testdir): + django_testdir.create_test_module( + """ + import pytest + + from django.conf import settings as django_settings + from django.db.models.signals import post_migrate + + @pytest.fixture + def check_settings_in_post_migrate(settings, transactional_db): + def receiver(sender, **kwargs): + assert not hasattr(django_settings, 'TRANSIENT_SETTING') + + post_migrate.connect(receiver, weak=False) + + def test_set_non_existent(settings, check_settings_in_post_migrate): + settings.TRANSIENT_SETTING = 1 + """ + ) + + result = django_testdir.runpytest_subprocess("-v") + assert result.ret == 0 + result.stdout.fnmatch_lines(["*test_set_non_existent PASSED*"]) + class TestLiveServer: def test_settings_before(self) -> None: