1
1
from __future__ import unicode_literals , absolute_import
2
2
3
+ import copy
3
4
from collections import OrderedDict
4
5
5
6
import django
6
7
from django .db import models , connections
7
- from django .db .models import F , ForeignObject
8
+ from django .db .models import F , ForeignObject , Value
8
9
from django .db .models .fields .related_descriptors import (
9
10
ReverseManyToOneDescriptor ,
10
11
ReverseOneToOneDescriptor ,
@@ -237,19 +238,28 @@ def get_extra_restriction(self, where_class, alias, related_alias):
237
238
where_class = where_class ,
238
239
)
239
240
241
+ @classmethod
242
+ def _resolve_expression_local_references (cls , expr , obj ):
243
+ if isinstance (expr , L ):
244
+ return expr ._relativity_resolve_for_instance (obj )
245
+ else :
246
+ for source_expr in expr .get_source_expressions ():
247
+ cls ._resolve_expression_local_references (source_expr , obj )
248
+ return expr
249
+
240
250
def get_forward_related_filter (self , obj ):
241
251
"""
242
252
Return the filter arguments which select the instances of self.model
243
253
that are related to obj.
244
254
"""
245
255
q = self .field .predicate
246
- q = q () if callable (q ) else q
256
+ q = q () if callable (q ) else copy . deepcopy ( q )
247
257
248
258
# If this is a simple restriction that can be expressed as an AND of
249
259
# two basic field lookups, we can return a dictionary of filters...
250
260
if q .connector == Q .AND and all (type (c ) == tuple for c in q .children ):
251
261
return {
252
- lookup : getattr ( obj , v . name ) if isinstance (v , L ) else v
262
+ lookup : self . _resolve_expression_local_references (v , obj )
253
263
for lookup , v in q .children
254
264
}
255
265
@@ -371,6 +381,11 @@ def relationship_related_query_name(self):
371
381
372
382
373
383
class L (F ):
384
+ def _relativity_resolve_for_instance (self , obj ):
385
+ val = getattr (obj , self .name )
386
+ self ._relativity_resolved_value = Value (val )
387
+ return val
388
+
374
389
def resolve_expression (
375
390
self ,
376
391
query = None ,
@@ -380,7 +395,10 @@ def resolve_expression(
380
395
for_save = False ,
381
396
simple_col = False ,
382
397
):
383
- # noinspection PyProtectedMember
384
- return super (L , self ).resolve_expression (
385
- query ._relationship_field_query , allow_joins , reuse , summarize , for_save
386
- )
398
+ if hasattr (self , "_relativity_resolved_value" ):
399
+ return self ._relativity_resolved_value
400
+ else :
401
+ # noinspection PyProtectedMember
402
+ return super (L , self ).resolve_expression (
403
+ query ._relationship_field_query , allow_joins , reuse , summarize , for_save
404
+ )
0 commit comments