mirror of
				https://github.com/django/django.git
				synced 2025-10-30 09:06:13 +00:00 
			
		
		
		
	Fixed #9308 -- Corrected the updated of nullable foreign key fields when deleting objects. Thanks to Bob Thomas for the fix, and markshep for the improvements on the test case.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10822 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -615,7 +615,7 @@ class QuerySet(object): | |||||||
|         clone = self._clone() |         clone = self._clone() | ||||||
|         clone.query.add_immediate_loading(fields) |         clone.query.add_immediate_loading(fields) | ||||||
|         return clone |         return clone | ||||||
|          |  | ||||||
|     ################################### |     ################################### | ||||||
|     # PUBLIC INTROSPECTION ATTRIBUTES # |     # PUBLIC INTROSPECTION ATTRIBUTES # | ||||||
|     ################################### |     ################################### | ||||||
| @@ -632,7 +632,7 @@ class QuerySet(object): | |||||||
|         else: |         else: | ||||||
|             return False |             return False | ||||||
|     ordered = property(ordered) |     ordered = property(ordered) | ||||||
|      |  | ||||||
|     ################### |     ################### | ||||||
|     # PRIVATE METHODS # |     # PRIVATE METHODS # | ||||||
|     ################### |     ################### | ||||||
| @@ -1007,7 +1007,7 @@ def delete_objects(seen_objs): | |||||||
|             update_query = sql.UpdateQuery(cls, connection) |             update_query = sql.UpdateQuery(cls, connection) | ||||||
|             for field, model in cls._meta.get_fields_with_model(): |             for field, model in cls._meta.get_fields_with_model(): | ||||||
|                 if (field.rel and field.null and field.rel.to in seen_objs and |                 if (field.rel and field.null and field.rel.to in seen_objs and | ||||||
|                         filter(lambda f: f.column == field.column, |                         filter(lambda f: f.column == field.rel.get_related_field().column, | ||||||
|                         field.rel.to._meta.fields)): |                         field.rel.to._meta.fields)): | ||||||
|                     if model: |                     if model: | ||||||
|                         sql.UpdateQuery(model, connection).clear_related(field, |                         sql.UpdateQuery(model, connection).clear_related(field, | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ class D(DefaultRepr, models.Model): | |||||||
| # D -> A | # D -> A | ||||||
|  |  | ||||||
| # So, we must delete Ds first of all, then Cs then Bs then As. | # So, we must delete Ds first of all, then Cs then Bs then As. | ||||||
| # However, if we start at As, we might find Bs first (in which  | # However, if we start at As, we might find Bs first (in which | ||||||
| # case things will be nice), or find Ds first. | # case things will be nice), or find Ds first. | ||||||
|  |  | ||||||
| # Some mutually dependent models, but nullable | # Some mutually dependent models, but nullable | ||||||
| @@ -96,7 +96,7 @@ CyclicDependency: There is a cyclic dependency of items to be processed. | |||||||
|  |  | ||||||
| >>> def clear_rel_obj_caches(models): | >>> def clear_rel_obj_caches(models): | ||||||
| ...     for m in models: | ...     for m in models: | ||||||
| ...         if hasattr(m._meta, '_related_objects_cache'):  | ...         if hasattr(m._meta, '_related_objects_cache'): | ||||||
| ...             del m._meta._related_objects_cache | ...             del m._meta._related_objects_cache | ||||||
|  |  | ||||||
| # Nice order | # Nice order | ||||||
| @@ -168,7 +168,16 @@ True | |||||||
| >>> o.keys() | >>> o.keys() | ||||||
| [<class 'modeltests.delete.models.F'>, <class 'modeltests.delete.models.E'>] | [<class 'modeltests.delete.models.F'>, <class 'modeltests.delete.models.E'>] | ||||||
|  |  | ||||||
|  | # temporarily replace the UpdateQuery class to verify that E.f is actually nulled out first | ||||||
|  | >>> import django.db.models.sql | ||||||
|  | >>> class LoggingUpdateQuery(django.db.models.sql.UpdateQuery): | ||||||
|  | ...     def clear_related(self, related_field, pk_list): | ||||||
|  | ...         print "CLEARING FIELD",related_field.name | ||||||
|  | ...         return super(LoggingUpdateQuery, self).clear_related(related_field, pk_list) | ||||||
|  | >>> original_class = django.db.models.sql.UpdateQuery | ||||||
|  | >>> django.db.models.sql.UpdateQuery = LoggingUpdateQuery | ||||||
| >>> e1.delete() | >>> e1.delete() | ||||||
|  | CLEARING FIELD f | ||||||
|  |  | ||||||
| >>> e2 = E() | >>> e2 = E() | ||||||
| >>> e2.save() | >>> e2.save() | ||||||
| @@ -185,6 +194,9 @@ True | |||||||
| [<class 'modeltests.delete.models.F'>, <class 'modeltests.delete.models.E'>] | [<class 'modeltests.delete.models.F'>, <class 'modeltests.delete.models.E'>] | ||||||
|  |  | ||||||
| >>> f2.delete() | >>> f2.delete() | ||||||
|  | CLEARING FIELD f | ||||||
|  |  | ||||||
|  | # Put this back to normal | ||||||
|  | >>> django.db.models.sql.UpdateQuery = original_class | ||||||
| """ | """ | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user