mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[5.0.x] Fixed #35238 -- Fixed database serialization crash when base managers use prefetch_related().
Regression in1391356276following deprecation in eedbf930287cb72e9afab1f7208c24b1146b0c4ec. Backport ofa084c5d35afrom main
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							e72fdc850a
						
					
				
				
					commit
					69e5b13c75
				
			| @@ -135,7 +135,10 @@ class BaseDatabaseCreation: | |||||||
|                             queryset = model._base_manager.using( |                             queryset = model._base_manager.using( | ||||||
|                                 self.connection.alias, |                                 self.connection.alias, | ||||||
|                             ).order_by(model._meta.pk.name) |                             ).order_by(model._meta.pk.name) | ||||||
|                             yield from queryset.iterator() |                             chunk_size = ( | ||||||
|  |                                 2000 if queryset._prefetch_related_lookups else None | ||||||
|  |                             ) | ||||||
|  |                             yield from queryset.iterator(chunk_size=chunk_size) | ||||||
|  |  | ||||||
|         # Serialize to a string |         # Serialize to a string | ||||||
|         out = StringIO() |         out = StringIO() | ||||||
|   | |||||||
| @@ -24,3 +24,7 @@ Bugfixes | |||||||
| * Fixed a regression in Django 5.0 that caused a crash of | * Fixed a regression in Django 5.0 that caused a crash of | ||||||
|   ``@sensitive_variables`` and ``@sensitive_post_parameters`` decorators on |   ``@sensitive_variables`` and ``@sensitive_post_parameters`` decorators on | ||||||
|   functions loaded from ``.pyc`` files (:ticket:`35187`). |   functions loaded from ``.pyc`` files (:ticket:`35187`). | ||||||
|  |  | ||||||
|  | * Fixed a regression in Django 5.0 that caused a crash when reloading a test | ||||||
|  |   database and a base queryset for a base manager used ``prefetch_related()`` | ||||||
|  |   (:ticket:`35238`). | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ from ..models import ( | |||||||
|     Object, |     Object, | ||||||
|     ObjectReference, |     ObjectReference, | ||||||
|     ObjectSelfReference, |     ObjectSelfReference, | ||||||
|  |     SchoolBus, | ||||||
|     SchoolClass, |     SchoolClass, | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -250,6 +251,22 @@ class TestDeserializeDbFromString(TransactionTestCase): | |||||||
|         self.assertIn('"model": "backends.schoolclass"', data) |         self.assertIn('"model": "backends.schoolclass"', data) | ||||||
|         self.assertIn('"year": 1000', data) |         self.assertIn('"year": 1000', data) | ||||||
|  |  | ||||||
|  |     def test_serialize_db_to_string_base_manager_with_prefetch_related(self): | ||||||
|  |         sclass = SchoolClass.objects.create( | ||||||
|  |             year=2000, last_updated=datetime.datetime.now() | ||||||
|  |         ) | ||||||
|  |         bus = SchoolBus.objects.create(number=1) | ||||||
|  |         bus.schoolclasses.add(sclass) | ||||||
|  |         with mock.patch("django.db.migrations.loader.MigrationLoader") as loader: | ||||||
|  |             # serialize_db_to_string() serializes only migrated apps, so mark | ||||||
|  |             # the backends app as migrated. | ||||||
|  |             loader_instance = loader.return_value | ||||||
|  |             loader_instance.migrated_apps = {"backends"} | ||||||
|  |             data = connection.creation.serialize_db_to_string() | ||||||
|  |         self.assertIn('"model": "backends.schoolbus"', data) | ||||||
|  |         self.assertIn('"model": "backends.schoolclass"', data) | ||||||
|  |         self.assertIn(f'"schoolclasses": [{sclass.pk}]', data) | ||||||
|  |  | ||||||
|  |  | ||||||
| class SkipTestClass: | class SkipTestClass: | ||||||
|     def skip_function(self): |     def skip_function(self): | ||||||
|   | |||||||
| @@ -32,6 +32,20 @@ class SchoolClass(models.Model): | |||||||
|     objects = SchoolClassManager() |     objects = SchoolClassManager() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class SchoolBusManager(models.Manager): | ||||||
|  |     def get_queryset(self): | ||||||
|  |         return super().get_queryset().prefetch_related("schoolclasses") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class SchoolBus(models.Model): | ||||||
|  |     number = models.IntegerField() | ||||||
|  |     schoolclasses = models.ManyToManyField("SchoolClass") | ||||||
|  |     objects = SchoolBusManager() | ||||||
|  |  | ||||||
|  |     class Meta: | ||||||
|  |         base_manager_name = "objects" | ||||||
|  |  | ||||||
|  |  | ||||||
| class VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ(models.Model): | class VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ(models.Model): | ||||||
|     primary_key_is_quite_long_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz = models.AutoField( |     primary_key_is_quite_long_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz = models.AutoField( | ||||||
|         primary_key=True |         primary_key=True | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user