mirror of
				https://github.com/django/django.git
				synced 2025-10-29 00:26:07 +00:00 
			
		
		
		
	[1.6.x] Fixed #23370 -- defer() + select_related() crashed with inherited models.
Backport of 6613ea6e3f from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							ce4057591a
						
					
				
				
					commit
					b877697472
				
			
							
								
								
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -60,6 +60,7 @@ answer newbie questions, and generally made Django that much better: | ||||
|     Mathieu Agopian <mathieu.agopian@gmail.com> | ||||
|     Roberto Aguilar <roberto@baremetal.io> | ||||
|     ajs <adi@sieker.info> | ||||
|     Akis Kesoglou <akiskesoglou@gmail.com> | ||||
|     alang@bright-green.com | ||||
|     A S Alam <aalam@users.sf.net> | ||||
|     Andi Albrecht <albrecht.andi@gmail.com> | ||||
|   | ||||
| @@ -1198,12 +1198,12 @@ def get_klass_info(klass, max_depth=0, cur_depth=0, requested=None, | ||||
|         init_list = [] | ||||
|         # Build the list of fields that *haven't* been requested | ||||
|         for field, model in klass._meta.get_concrete_fields_with_model(): | ||||
|             if field.name not in load_fields: | ||||
|                 skip.add(field.attname) | ||||
|             elif from_parent and issubclass(from_parent, model.__class__): | ||||
|             if from_parent and model and issubclass(from_parent, model): | ||||
|                 # Avoid loading fields already loaded for parent model for | ||||
|                 # child models. | ||||
|                 continue | ||||
|             elif field.name not in load_fields: | ||||
|                 skip.add(field.attname) | ||||
|             else: | ||||
|                 init_list.append(field.attname) | ||||
|         # Retrieve all the requested fields | ||||
|   | ||||
| @@ -4,10 +4,13 @@ Django 1.6.7 release notes | ||||
|  | ||||
| *Under development* | ||||
|  | ||||
| Django 1.6.7 fixes a regression in the 1.6.6 security release. | ||||
| Django 1.6.7 fixes several bugs in 1.6.6, including a regression related to | ||||
| a security fix in that release. | ||||
|  | ||||
| Bugfixes | ||||
| ======== | ||||
|  | ||||
| * Allowed inherited and m2m fields to be referenced in the admin | ||||
|   :ticket:`23329` | ||||
|   (:ticket:`23329`). | ||||
| * Fixed a crash when using ``QuerySet.defer()`` with ``select_related()`` | ||||
|   (:ticket:`23370`). | ||||
|   | ||||
| @@ -275,6 +275,43 @@ class ModelInheritanceTests(TestCase): | ||||
|             lambda: ItalianRestaurant.objects.select_related("chef")[0].chef | ||||
|         ) | ||||
|  | ||||
|     def test_select_related_defer(self): | ||||
|         """ | ||||
|         #23370 - Should be able to defer child fields when using | ||||
|         select_related() from parent to child. | ||||
|         """ | ||||
|         Restaurant.objects.create( | ||||
|             name="Demon Dogs", | ||||
|             address="944 W. Fullerton", | ||||
|             serves_hot_dogs=True, | ||||
|             serves_pizza=False, | ||||
|             rating=2, | ||||
|         ) | ||||
|         ItalianRestaurant.objects.create( | ||||
|             name="Ristorante Miron", | ||||
|             address="1234 W. Ash", | ||||
|             serves_hot_dogs=False, | ||||
|             serves_pizza=False, | ||||
|             serves_gnocchi=True, | ||||
|             rating=4, | ||||
|         ) | ||||
|  | ||||
|         qs = (Restaurant.objects | ||||
|             .select_related("italianrestaurant") | ||||
|             .defer("italianrestaurant__serves_gnocchi") | ||||
|             .order_by("rating")) | ||||
|  | ||||
|         # Test that the field was actually defered | ||||
|         with self.assertNumQueries(2): | ||||
|             objs = list(qs.all()) | ||||
|             self.assertTrue(objs[1].italianrestaurant.serves_gnocchi) | ||||
|  | ||||
|         # Test that model fields where assigned correct values | ||||
|         self.assertEqual(qs[0].name, 'Demon Dogs') | ||||
|         self.assertEqual(qs[0].rating, 2) | ||||
|         self.assertEqual(qs[1].italianrestaurant.name, 'Ristorante Miron') | ||||
|         self.assertEqual(qs[1].italianrestaurant.rating, 4) | ||||
|  | ||||
|     def test_mixin_init(self): | ||||
|         m = MixinModel() | ||||
|         self.assertEqual(m.other_attr, 1) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user