mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #18304 -- Optimized save() when update_can_self_select=False
Databases with update_can_self_select = False (MySQL for example) generated non-necessary queries when saving a multitable inherited model, and when the save resulted in update.
This commit is contained in:
		| @@ -1015,6 +1015,12 @@ class SQLUpdateCompiler(SQLCompiler): | ||||
|         query.extra = {} | ||||
|         query.select = [] | ||||
|         query.add_fields([query.model._meta.pk.name]) | ||||
|         # Recheck the count - it is possible that fiddling with the select | ||||
|         # fields above removes tables from the query. Refs #18304. | ||||
|         count = query.count_active_tables() | ||||
|         if not self.query.related_updates and count == 1: | ||||
|             return | ||||
|  | ||||
|         must_pre_select = count > 1 and not self.connection.features.update_can_self_select | ||||
|  | ||||
|         # Now we adjust the current query: reset the where clause and get rid | ||||
|   | ||||
| @@ -275,3 +275,21 @@ class ModelInheritanceTests(TestCase): | ||||
|     def test_mixin_init(self): | ||||
|         m = MixinModel() | ||||
|         self.assertEqual(m.other_attr, 1) | ||||
|  | ||||
|     def test_update_query_counts(self): | ||||
|         """ | ||||
|         Test that update queries do not generate non-necessary queries. | ||||
|         Refs #18304. | ||||
|         """ | ||||
|         c = Chef.objects.create(name="Albert") | ||||
|         ir = ItalianRestaurant.objects.create( | ||||
|             name="Ristorante Miron", | ||||
|             address="1234 W. Ash", | ||||
|             serves_hot_dogs=False, | ||||
|             serves_pizza=False, | ||||
|             serves_gnocchi=True, | ||||
|             rating=4, | ||||
|             chef=c | ||||
|         ) | ||||
|         with self.assertNumQueries(6): | ||||
|             ir.save() | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| from __future__ import absolute_import | ||||
|  | ||||
| from django.test import TestCase, skipUnlessDBFeature | ||||
| from django.test import TestCase | ||||
| from django.db.models.signals import pre_save, post_save | ||||
| from .models import Person, Employee, ProxyEmployee, Profile, Account | ||||
|  | ||||
| @@ -123,9 +123,6 @@ class UpdateOnlyFieldsTests(TestCase): | ||||
|         self.assertEqual(len(pre_save_data), 0) | ||||
|         self.assertEqual(len(post_save_data), 0) | ||||
|  | ||||
|     # A bug in SQLUpdateCompiler prevents this test from succeeding on MySQL | ||||
|     # Require update_can_self_select for this test for now. Refs #18304. | ||||
|     @skipUnlessDBFeature('update_can_self_select') | ||||
|     def test_num_queries_inheritance(self): | ||||
|         s = Employee.objects.create(name='Sara', gender='F') | ||||
|         s.employee_num = 1 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user