mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[4.1.x] Fixed #33422 -- Improved docs about isolating apps.
Backport of 90d2f9f416 from main
			
			
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							6c0ee61797
						
					
				
				
					commit
					aed1a73e0a
				
			| @@ -522,25 +522,8 @@ Isolating model registration | ||||
|  | ||||
| To avoid polluting the global :attr:`~django.apps.apps` registry and prevent | ||||
| unnecessary table creation, models defined in a test method should be bound to | ||||
| a temporary ``Apps`` instance:: | ||||
|  | ||||
|     from django.apps.registry import Apps | ||||
|     from django.db import models | ||||
|     from django.test import SimpleTestCase | ||||
|  | ||||
|     class TestModelDefinition(SimpleTestCase): | ||||
|         def test_model_definition(self): | ||||
|             test_apps = Apps(['app_label']) | ||||
|  | ||||
|             class TestModel(models.Model): | ||||
|                 class Meta: | ||||
|                     apps = test_apps | ||||
|             ... | ||||
|  | ||||
| .. function:: django.test.utils.isolate_apps(*app_labels, attr_name=None, kwarg_name=None) | ||||
|  | ||||
| Since this pattern involves a lot of boilerplate, Django provides the | ||||
| :func:`~django.test.utils.isolate_apps` decorator. It's used like this:: | ||||
| a temporary ``Apps`` instance. To do this, use the | ||||
| :func:`~django.test.utils.isolate_apps` decorator:: | ||||
|  | ||||
|     from django.db import models | ||||
|     from django.test import SimpleTestCase | ||||
| @@ -581,45 +564,3 @@ Since this pattern involves a lot of boilerplate, Django provides the | ||||
|                     class Meta: | ||||
|                         app_label = 'other_app_label' | ||||
|                 ... | ||||
|  | ||||
| The decorator can also be applied to classes:: | ||||
|  | ||||
|     from django.db import models | ||||
|     from django.test import SimpleTestCase | ||||
|     from django.test.utils import isolate_apps | ||||
|  | ||||
|     @isolate_apps('app_label') | ||||
|     class TestModelDefinition(SimpleTestCase): | ||||
|         def test_model_definition(self): | ||||
|             class TestModel(models.Model): | ||||
|                 pass | ||||
|             ... | ||||
|  | ||||
| The temporary ``Apps`` instance used to isolate model registration can be | ||||
| retrieved as an attribute when used as a class decorator by using the | ||||
| ``attr_name`` parameter:: | ||||
|  | ||||
|     from django.db import models | ||||
|     from django.test import SimpleTestCase | ||||
|     from django.test.utils import isolate_apps | ||||
|  | ||||
|     @isolate_apps('app_label', attr_name='apps') | ||||
|     class TestModelDefinition(SimpleTestCase): | ||||
|         def test_model_definition(self): | ||||
|             class TestModel(models.Model): | ||||
|                 pass | ||||
|             self.assertIs(self.apps.get_model('app_label', 'TestModel'), TestModel) | ||||
|  | ||||
| Or as an argument on the test method when used as a method decorator by using | ||||
| the ``kwarg_name`` parameter:: | ||||
|  | ||||
|     from django.db import models | ||||
|     from django.test import SimpleTestCase | ||||
|     from django.test.utils import isolate_apps | ||||
|  | ||||
|     class TestModelDefinition(SimpleTestCase): | ||||
|         @isolate_apps('app_label', kwarg_name='apps') | ||||
|         def test_model_definition(self, apps): | ||||
|             class TestModel(models.Model): | ||||
|                 pass | ||||
|             self.assertIs(apps.get_model('app_label', 'TestModel'), TestModel) | ||||
|   | ||||
| @@ -1403,6 +1403,69 @@ LOCALE_PATHS, LANGUAGE_CODE      Default translation and loaded translations | ||||
| MEDIA_ROOT, DEFAULT_FILE_STORAGE Default file storage | ||||
| ================================ ======================== | ||||
|  | ||||
| Isolating apps | ||||
| -------------- | ||||
|  | ||||
| .. function:: utils.isolate_apps(*app_labels, attr_name=None, kwarg_name=None) | ||||
|  | ||||
|     Registers the models defined within a wrapped context into their own | ||||
|     isolated :attr:`~django.apps.apps` registry. This functionality is useful | ||||
|     when creating model classes for tests, as the classes will be cleanly | ||||
|     deleted afterward, and there is no risk of name collisions. | ||||
|  | ||||
|     The app labels which the isolated registry should contain must be passed as | ||||
|     individual arguments. You can use ``isolate_apps()`` as a decorator or a | ||||
|     context manager. For example:: | ||||
|  | ||||
|         from django.db import models | ||||
|         from django.test import SimpleTestCase | ||||
|         from django.test.utils import isolate_apps | ||||
|  | ||||
|         class MyModelTests(SimpleTestCase): | ||||
|  | ||||
|             @isolate_apps("app_label") | ||||
|             def test_model_definition(self): | ||||
|                 class TestModel(models.Model): | ||||
|                     pass | ||||
|                 ... | ||||
|  | ||||
|     … or:: | ||||
|  | ||||
|         with isolate_apps("app_label"): | ||||
|             class TestModel(models.Model): | ||||
|                 pass | ||||
|             ... | ||||
|  | ||||
|     The decorator form can also be applied to classes. | ||||
|  | ||||
|     Two optional keyword arguments can be specified: | ||||
|  | ||||
|     * ``attr_name``: attribute assigned the isolated registry if used as a | ||||
|       class decorator. | ||||
|     * ``kwarg_name``: keyword argument passing the isolated registry if used as | ||||
|       a function decorator. | ||||
|  | ||||
|     The temporary ``Apps`` instance used to isolate model registration can be | ||||
|     retrieved as an attribute when used as a class decorator by using the | ||||
|     ``attr_name`` parameter:: | ||||
|  | ||||
|         @isolate_apps("app_label", attr_name="apps") | ||||
|         class TestModelDefinition(SimpleTestCase): | ||||
|             def test_model_definition(self): | ||||
|                 class TestModel(models.Model): | ||||
|                     pass | ||||
|                 self.assertIs(self.apps.get_model("app_label", "TestModel"), TestModel) | ||||
|  | ||||
|     … or alternatively as an argument on the test method when used as a method | ||||
|     decorator by using the ``kwarg_name`` parameter:: | ||||
|  | ||||
|         class TestModelDefinition(SimpleTestCase): | ||||
|             @isolate_apps("app_label", kwarg_name="apps") | ||||
|             def test_model_definition(self, apps): | ||||
|                 class TestModel(models.Model): | ||||
|                     pass | ||||
|                 self.assertIs(apps.get_model("app_label", "TestModel"), TestModel) | ||||
|  | ||||
| .. _emptying-test-outbox: | ||||
|  | ||||
| Emptying the test outbox | ||||
|   | ||||
		Reference in New Issue
	
	Block a user