@@ -11,14 +11,26 @@ def __init__(self, msg, protected_objects):
11
11
super ().__init__ (msg , protected_objects )
12
12
13
13
14
- def CASCADE (collector , field , sub_objs , using ):
14
+ class OnDelete (object ):
15
+ with_db = False
16
+
17
+ def __init__ (self , name , operation , value = None ):
18
+ self .name = name
19
+ self .operation = operation
20
+ self .value = value
21
+
22
+ def __call__ (self , * args , ** kwargs ):
23
+ return self .operation (* args , ** kwargs )
24
+
25
+
26
+ def application_cascade (collector , field , sub_objs , using ):
15
27
collector .collect (sub_objs , source = field .remote_field .model ,
16
28
source_attr = field .name , nullable = field .null )
17
29
if field .null and not connections [using ].features .can_defer_constraint_checks :
18
30
collector .add_field_update (field , None , sub_objs )
19
31
20
32
21
- def PROTECT (collector , field , sub_objs , using ):
33
+ def application_protect (collector , field , sub_objs , using ):
22
34
raise ProtectedError (
23
35
"Cannot delete some instances of model '%s' because they are "
24
36
"referenced through a protected foreign key: '%s.%s'" % (
@@ -28,27 +40,44 @@ def PROTECT(collector, field, sub_objs, using):
28
40
)
29
41
30
42
31
- def SET (value ):
43
+ def application_set (value ):
32
44
if callable (value ):
33
45
def set_on_delete (collector , field , sub_objs , using ):
34
46
collector .add_field_update (field , value (), sub_objs )
35
47
else :
36
48
def set_on_delete (collector , field , sub_objs , using ):
37
49
collector .add_field_update (field , value , sub_objs )
38
50
set_on_delete .deconstruct = lambda : ('django.db.models.SET' , (value ,), {})
39
- return set_on_delete
51
+ return OnDelete ( 'SET' , set_on_delete , value )
40
52
41
53
42
- def SET_NULL (collector , field , sub_objs , using ):
54
+ def application_set_null (collector , field , sub_objs , using ):
43
55
collector .add_field_update (field , None , sub_objs )
44
56
45
57
46
- def SET_DEFAULT (collector , field , sub_objs , using ):
58
+ def application_set_default (collector , field , sub_objs , using ):
47
59
collector .add_field_update (field , field .get_default (), sub_objs )
48
60
49
61
50
- def DO_NOTHING (collector , field , sub_objs , using ):
51
- pass
62
+ CASCADE = OnDelete ('CASCADE' , application_cascade )
63
+ PROTECT = OnDelete ('PROTECT' , application_protect )
64
+ SET = OnDelete ('SET' , application_set )
65
+ SET_NULL = OnDelete ('SET_NULL' , application_set_null )
66
+ SET_DEFAULT = OnDelete ('SET_DEFAULT' , application_set_default )
67
+
68
+
69
+ class DatabaseOnDelete (OnDelete ):
70
+ with_db = True
71
+
72
+ def __call__ (self , collector , field , sub_objs , using ):
73
+ pass
74
+
75
+ def as_sql (self , connection ):
76
+ return connection .ops .fk_on_delete_sql (self .operation )
77
+
78
+
79
+ DO_NOTHING = DatabaseOnDelete ('DO_NOTHING' , 'NO ACTION' )
80
+ DB_CASCADE = DatabaseOnDelete ('DB_CASCADE' , 'CASCADE' )
52
81
53
82
54
83
def get_candidate_relations_to_delete (opts ):
@@ -144,7 +173,7 @@ def can_fast_delete(self, objs, from_field=None):
144
173
# Foreign keys pointing to this model, both from m2m and other
145
174
# models.
146
175
for related in get_candidate_relations_to_delete (opts ):
147
- if related .field .remote_field .on_delete is not DO_NOTHING :
176
+ if related .field .remote_field .on_delete . with_db is False :
148
177
return False
149
178
for field in model ._meta .private_fields :
150
179
if hasattr (field , 'bulk_related_objects' ):
@@ -211,7 +240,7 @@ def collect(self, objs, source=None, nullable=False, collect_related=True,
211
240
if keep_parents and related .model in parents :
212
241
continue
213
242
field = related .field
214
- if field .remote_field .on_delete == DO_NOTHING :
243
+ if field .remote_field .on_delete . with_db :
215
244
continue
216
245
batches = self .get_del_batches (new_objs , field )
217
246
for batch in batches :
0 commit comments