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 | 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 | unnecessary table creation, models defined in a test method should be bound to | ||||||
| a temporary ``Apps`` instance:: | a temporary ``Apps`` instance. To do this, use the | ||||||
|  | :func:`~django.test.utils.isolate_apps` decorator:: | ||||||
|     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:: |  | ||||||
|  |  | ||||||
|     from django.db import models |     from django.db import models | ||||||
|     from django.test import SimpleTestCase |     from django.test import SimpleTestCase | ||||||
| @@ -581,45 +564,3 @@ Since this pattern involves a lot of boilerplate, Django provides the | |||||||
|                     class Meta: |                     class Meta: | ||||||
|                         app_label = 'other_app_label' |                         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 | 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-test-outbox: | ||||||
|  |  | ||||||
| Emptying the test outbox | Emptying the test outbox | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user