mirror of
https://github.com/django/django.git
synced 2025-09-23 02:33:31 +00:00
Fixed #12663 -- Formalized the Model._meta API for retrieving fields.
Thanks to Russell Keith-Magee for mentoring this Google Summer of Code 2014 project and everyone else who helped with the patch!
This commit is contained in:
parent
749d23251b
commit
fb48eb0581
58 changed files with 2851 additions and 1195 deletions
|
@ -252,9 +252,8 @@ class QuerySet(object):
|
|||
# If only/defer clauses have been specified,
|
||||
# build the list of fields that are to be loaded.
|
||||
if only_load:
|
||||
for field, model in self.model._meta.get_concrete_fields_with_model():
|
||||
if model is None:
|
||||
model = self.model
|
||||
for field in self.model._meta.concrete_fields:
|
||||
model = field.model._meta.model
|
||||
try:
|
||||
if field.name in only_load[model]:
|
||||
# Add a field that has been explicitly included
|
||||
|
@ -818,7 +817,7 @@ class QuerySet(object):
|
|||
obj = self._clone()
|
||||
names = getattr(self, '_fields', None)
|
||||
if names is None:
|
||||
names = set(self.model._meta.get_all_field_names())
|
||||
names = {f.name for f in self.model._meta.get_fields()}
|
||||
|
||||
# Add the annotations to the query
|
||||
for alias, annotation in annotations.items():
|
||||
|
@ -1329,7 +1328,8 @@ def get_klass_info(klass, max_depth=0, cur_depth=0, requested=None,
|
|||
skip = set()
|
||||
init_list = []
|
||||
# Build the list of fields that *haven't* been requested
|
||||
for field, model in klass._meta.get_concrete_fields_with_model():
|
||||
for field in klass._meta.concrete_fields:
|
||||
model = field.model._meta.concrete_model
|
||||
if from_parent and model and issubclass(from_parent, model):
|
||||
# Avoid loading fields already loaded for parent model for
|
||||
# child models.
|
||||
|
@ -1381,18 +1381,19 @@ def get_klass_info(klass, max_depth=0, cur_depth=0, requested=None,
|
|||
|
||||
reverse_related_fields = []
|
||||
if restricted:
|
||||
for o in klass._meta.get_all_related_objects():
|
||||
for o in klass._meta.related_objects:
|
||||
if o.field.unique and select_related_descend(o.field, restricted, requested,
|
||||
only_load.get(o.model), reverse=True):
|
||||
only_load.get(o.related_model), reverse=True):
|
||||
next = requested[o.field.related_query_name()]
|
||||
parent = klass if issubclass(o.model, klass) else None
|
||||
klass_info = get_klass_info(o.model, max_depth=max_depth, cur_depth=cur_depth + 1,
|
||||
parent = klass if issubclass(o.related_model, klass) else None
|
||||
klass_info = get_klass_info(o.related_model, max_depth=max_depth, cur_depth=cur_depth + 1,
|
||||
requested=next, only_load=only_load, from_parent=parent)
|
||||
reverse_related_fields.append((o.field, klass_info))
|
||||
if field_names:
|
||||
pk_idx = field_names.index(klass._meta.pk.attname)
|
||||
else:
|
||||
pk_idx = klass._meta.pk_index()
|
||||
meta = klass._meta
|
||||
pk_idx = meta.concrete_fields.index(meta.pk)
|
||||
|
||||
return klass, field_names, field_count, related_fields, reverse_related_fields, pk_idx
|
||||
|
||||
|
@ -1485,7 +1486,10 @@ def get_cached_row(row, index_start, using, klass_info, offset=0,
|
|||
for f, klass_info in reverse_related_fields:
|
||||
# Transfer data from this object to childs.
|
||||
parent_data = []
|
||||
for rel_field, rel_model in klass_info[0]._meta.get_fields_with_model():
|
||||
for rel_field in klass_info[0]._meta.fields:
|
||||
rel_model = rel_field.model._meta.concrete_model
|
||||
if rel_model == klass_info[0]._meta.model:
|
||||
rel_model = None
|
||||
if rel_model is not None and isinstance(obj, rel_model):
|
||||
parent_data.append((rel_field, getattr(obj, rel_field.attname)))
|
||||
# Recursively retrieve the data for the related object
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue