Code

Ticket #10262: delete_cascade_option_with_admin_r9834.diff

File delete_cascade_option_with_admin_r9834.diff, 3.7 KB (added by msaelices, 5 years ago)

Updated admin to not display objects not deleted (because delete_cascade was False)

Line 
1Index: django/contrib/admin/util.py
2===================================================================
3--- django/contrib/admin/util.py        (revisión: 9834)
4+++ django/contrib/admin/util.py        (copia de trabajo)
5@@ -98,7 +98,7 @@
6                         sub_obj._get_pk_val(),
7                         escape(sub_obj))), []])
8                 get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2, admin_site)
9-        else:
10+        elif related.field.delete_cascade:
11             has_related_objs = False
12             for sub_obj in getattr(obj, rel_opts_name).all():
13                 has_related_objs = True
14Index: django/db/models/base.py
15===================================================================
16--- django/db/models/base.py    (revisión: 9834)
17+++ django/db/models/base.py    (copia de trabajo)
18@@ -11,7 +11,7 @@
19 import django.db.models.manager     # Imported to register signal handler.
20 from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError
21 from django.db.models.fields import AutoField, FieldDoesNotExist
22-from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField
23+from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField, RelatedObject
24 from django.db.models.query import delete_objects, Q, CollectedObjects
25 from django.db.models.options import Options
26 from django.db import connection, transaction, DatabaseError
27@@ -456,6 +456,12 @@
28     def delete(self):
29         assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
30 
31+        # Clear all related object with delete_cascade=False
32+        for field in self._meta.get_all_fields():
33+            if isinstance(field, RelatedObject) and not field.field.delete_cascade:
34+                related_manager = getattr(self, field.get_accessor_name())
35+                related_manager.clear()
36+
37         # Find all the objects than need to be deleted.
38         seen_objs = CollectedObjects()
39         self._collect_sub_objects(seen_objs)
40Index: django/db/models/options.py
41===================================================================
42--- django/db/models/options.py (revisión: 9834)
43+++ django/db/models/options.py (copia de trabajo)
44@@ -283,6 +283,18 @@
45             raise FieldDoesNotExist('%s has no field named %r'
46                     % (self.object_name, name))
47 
48+    def get_all_fields(self):
49+        """
50+        Returns a list of all fields that are possible for this model
51+        (including reverse relation names).
52+        """
53+        try:
54+            cache = self._name_map
55+        except AttributeError:
56+            cache = self.init_name_map()
57+        fields = [ r[0] for r in cache.values() ]
58+        return fields
59+
60     def get_all_field_names(self):
61         """
62         Returns a list of all field names that are possible for this model
63Index: django/db/models/fields/related.py
64===================================================================
65--- django/db/models/fields/related.py  (revisión: 9834)
66+++ django/db/models/fields/related.py  (copia de trabajo)
67@@ -646,9 +646,13 @@
68             limit_choices_to=kwargs.pop('limit_choices_to', None),
69             lookup_overrides=kwargs.pop('lookup_overrides', None),
70             parent_link=kwargs.pop('parent_link', False))
71+
72+        self.delete_cascade = kwargs.pop('delete_cascade', True)
73+
74         Field.__init__(self, **kwargs)
75 
76         self.db_index = True
77+        assert self.null or self.delete_cascade, "%s cannot define a not null relation (null=False) without deleting cascade (delete_cascade=False)" % self.__class__.__name__
78 
79     def get_attname(self):
80         return '%s_id' % self.name