2
2
PolymorphicQuerySet support functions
3
3
"""
4
4
5
- import copy
6
5
from collections import deque
7
6
8
7
from django .apps import apps
@@ -80,6 +79,35 @@ def tree_node_correct_field_specs(my_model, node):
80
79
return potential_q_object
81
80
82
81
82
+ def _deepcopy_q_object (q ):
83
+ """
84
+ Make a deepcopy of a Q-object.
85
+ """
86
+
87
+ def _copy_child (child ):
88
+ if isinstance (child , tuple ):
89
+ return child # tuples are immutable, no need to make a copy.
90
+ elif isinstance (child , Q ):
91
+ return _deepcopy_q_object (child )
92
+ else :
93
+ raise RuntimeError ("Unknown child type: %s" , type (child ))
94
+
95
+ children = [_copy_child (c ) for c in q .children ]
96
+
97
+ if hasattr (q , "copy" ): # Django 4.2+
98
+ obj = q .copy ()
99
+ # This assignment of obj.children from children (created above)
100
+ # is required for test_query_filter_exclude_is_immutable to pass
101
+ # because somehow the capitalization changed for q_to_reuse?
102
+ #
103
+ # assert q_to_reuse.children == untouched_q_object.children
104
+ # AssertionError: assert [('model2b__f... 'something')] == [('Model2B___... 'something')]
105
+ obj .children = children
106
+ else :
107
+ obj = Q (* children , _connector = q .connector , _negated = q .negated )
108
+ return obj
109
+
110
+
83
111
def translate_polymorphic_filter_definitions_in_args (queryset_model , args , using = DEFAULT_DB_ALIAS ):
84
112
"""
85
113
Translate the non-keyword argument list for PolymorphicQuerySet.filter()
@@ -92,7 +120,8 @@ def translate_polymorphic_filter_definitions_in_args(queryset_model, args, using
92
120
Returns: modified Q objects
93
121
"""
94
122
return [
95
- translate_polymorphic_Q_object (queryset_model , copy .deepcopy (q ), using = using ) for q in args
123
+ translate_polymorphic_Q_object (queryset_model , _deepcopy_q_object (q ), using = using )
124
+ for q in args
96
125
]
97
126
98
127
0 commit comments