Ticket #7270: django_select_related_onetoone_r10448.patch
File django_select_related_onetoone_r10448.patch, 6.9 KB (added by , 16 years ago) |
---|
-
db/models/sql/query.py
1391 1391 self.fill_related_selections(f.rel.to._meta, alias, cur_depth + 1, 1392 1392 used, next, restricted, new_nullable, dupe_set, avoid) 1393 1393 1394 # Do reverse columns, but only the ones in the requested list. 1395 if restricted: 1396 related_fields = [(x.field, x.model) for x in opts.get_all_related_objects() if x.field.unique] 1397 for f, model in related_fields: 1398 if f.rel.parent_link or f.related_query_name() not in requested: 1399 continue 1400 table = model._meta.db_table 1401 if nullable or f.null: 1402 promote = True 1403 else: 1404 promote = False 1405 alias = self.join((root_alias, table, f.rel.get_related_field().column, 1406 f.column), exclusions=used, 1407 promote=promote, reuse=used) 1408 used.add(alias) 1409 1410 self.related_select_cols.extend([(alias, f2.column) 1411 for f2 in model._meta.fields]) 1412 self.related_select_fields.extend(model._meta.fields) 1413 1414 next = requested.get(f.related_query_name(), {}) 1415 #if nullable is not None: 1416 # new_nullable = nullable 1417 #else: 1418 # new_nullable = f.null 1419 if f.null is not None: 1420 new_nullable = f.null 1421 else: 1422 new_nullable = None 1423 self.fill_related_selections(model._meta, table, cur_depth + 1, 1424 used, next, restricted, new_nullable) 1425 1394 1426 def add_aggregate(self, aggregate, model, alias, is_summary): 1395 1427 """ 1396 1428 Adds a single aggregate expression to the Query -
db/models/options.py
47 47 self.proxy_for_model = None 48 48 self.parents = SortedDict() 49 49 self.duplicate_targets = {} 50 self.reverse_field_cache = {} 50 51 51 52 # To handle various inheritance situations, we need to track where 52 53 # managers came from (concrete or abstract base classes). -
db/models/fields/related.py
1 import types 1 2 from django.db import connection, transaction 2 3 from django.db.backends import util 3 4 from django.db.models import signals, get_model … … 178 179 # SingleRelatedObjectDescriptor instance. 179 180 def __init__(self, related): 180 181 self.related = related 181 self.cache_name = '_%s_cache' % related.get_accessor_name() 182 #self.cache_name = '_%s_cache' % related.get_accessor_name() 183 cache_name = '_%s_cache' % related.field.related_query_name() 184 # Contribute to the parent model for later lookup. 185 related.parent_model._meta.reverse_field_cache[related.field.related_query_name()] = cache_name 186 self.cache_name = cache_name 182 187 183 188 def __get__(self, instance, instance_type=None): 184 189 if instance is None: … … 291 296 # attribute is a ForeignRelatedObjectsDescriptor instance. 292 297 def __init__(self, related): 293 298 self.related = related # RelatedObject instance 299 if related.field.unique: 300 cache_name = '_%s_cache' % related.field.related_query_name() 301 # Contribute to the parent model for later lookup. 302 related.parent_model._meta.reverse_field_cache[related.field.related_query_name()] = cache_name 303 self.cache_name = cache_name 294 304 295 305 def __get__(self, instance, instance_type=None): 296 306 if instance is None: … … 309 319 if self.related.field.null: 310 320 manager.clear() 311 321 manager.add(*value) 322 # Cache the value specially if from a unique set. 323 if self.related.field.unique: 324 self.cache_name = value 312 325 313 326 def delete_manager(self, instance): 314 327 """ … … 325 338 """ 326 339 rel_field = self.related.field 327 340 rel_model = self.related.model 341 if rel_field.unique: 342 cache_name = self.cache_name 328 343 329 344 class RelatedManager(superclass): 330 345 def get_query_set(self): … … 369 384 obj.save() 370 385 clear.alters_data = True 371 386 387 if rel_field.unique: 388 def all(self): 389 try: 390 result = getattr(instance, cache_name) 391 if isinstance(result, (types.TupleType, types.ListType)): 392 return result 393 else: 394 return [result] 395 except AttributeError, ae: 396 return superclass.get_query_set(self) 397 372 398 manager = RelatedManager() 373 399 attname = rel_field.rel.get_related_field().name 374 400 manager.core_filters = {'%s__%s' % (rel_field.name, attname): -
db/models/query.py
937 937 obj = klass(*fields) 938 938 939 939 index_end = index_start + field_count + offset 940 940 941 for f in klass._meta.fields: 941 942 if not select_related_descend(f, restricted, requested): 942 943 continue … … 950 951 rel_obj, index_end = cached_row 951 952 if obj is not None: 952 953 setattr(obj, f.get_cache_name(), rel_obj) 954 955 # Do the reverse cache if the field is a unique relation. 956 if f.unique: 957 cache_var_name = rel_obj._meta.reverse_field_cache[f.related_query_name()] 958 setattr(rel_obj, cache_var_name, obj) 959 960 if restricted: 961 related_fields = [(x.field, x.model) for x in klass._meta.get_all_related_objects() if x.field.unique] 962 for f, model in related_fields: 963 if f.related_query_name() not in requested: 964 continue 965 966 next = requested.get(f.related_query_name(), {}) 967 cached_row = get_cached_row(model, row, index_end, max_depth, 968 cur_depth+1, next) 969 if cached_row: 970 rel_obj, index_end = cached_row 971 if rel_obj is not None: 972 setattr(rel_obj, f.get_cache_name(), obj) 973 974 # Now do the reverse cache. 975 cache_var_name = obj._meta.reverse_field_cache[f.related_query_name()] 976 setattr(obj, cache_var_name, rel_obj) 977 953 978 return obj, index_end 954 979 955 980 def delete_objects(seen_objs):