From 40dc588a372375608701f7e521dea6d860a49eb2 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 15 Sep 2014 09:50:51 +0100 Subject: Drop label from serializer fields when not needed --- rest_framework/utils/model_meta.py | 99 ++++++++++++++++++++++++++++++++++++++ rest_framework/utils/modelinfo.py | 99 -------------------------------------- 2 files changed, 99 insertions(+), 99 deletions(-) create mode 100644 rest_framework/utils/model_meta.py delete mode 100644 rest_framework/utils/modelinfo.py (limited to 'rest_framework/utils') diff --git a/rest_framework/utils/model_meta.py b/rest_framework/utils/model_meta.py new file mode 100644 index 00000000..960fa4d0 --- /dev/null +++ b/rest_framework/utils/model_meta.py @@ -0,0 +1,99 @@ +""" +Helper functions for returning the field information that is associated +with a model class. This includes returning all the forward and reverse +relationships and their associated metadata. +""" +from collections import namedtuple +from django.db import models +from django.utils import six +from django.utils.datastructures import SortedDict +import inspect + +FieldInfo = namedtuple('FieldResult', ['pk', 'fields', 'forward_relations', 'reverse_relations']) +RelationInfo = namedtuple('RelationInfo', ['field', 'related', 'to_many', 'has_through_model']) + + +def _resolve_model(obj): + """ + Resolve supplied `obj` to a Django model class. + + `obj` must be a Django model class itself, or a string + representation of one. Useful in situtations like GH #1225 where + Django may not have resolved a string-based reference to a model in + another model's foreign key definition. + + String representations should have the format: + 'appname.ModelName' + """ + if isinstance(obj, six.string_types) and len(obj.split('.')) == 2: + app_name, model_name = obj.split('.') + return models.get_model(app_name, model_name) + elif inspect.isclass(obj) and issubclass(obj, models.Model): + return obj + raise ValueError("{0} is not a Django model".format(obj)) + + +def get_field_info(model): + """ + Given a model class, returns a `FieldInfo` instance containing metadata + about the various field types on the model. + """ + opts = model._meta.concrete_model._meta + + # Deal with the primary key. + pk = opts.pk + while pk.rel and pk.rel.parent_link: + # If model is a child via multitable inheritance, use parent's pk. + pk = pk.rel.to._meta.pk + + # Deal with regular fields. + fields = SortedDict() + for field in [field for field in opts.fields if field.serialize and not field.rel]: + fields[field.name] = field + + # Deal with forward relationships. + forward_relations = SortedDict() + for field in [field for field in opts.fields if field.serialize and field.rel]: + forward_relations[field.name] = RelationInfo( + field=field, + related=_resolve_model(field.rel.to), + to_many=False, + has_through_model=False + ) + + # Deal with forward many-to-many relationships. + for field in [field for field in opts.many_to_many if field.serialize]: + forward_relations[field.name] = RelationInfo( + field=field, + related=_resolve_model(field.rel.to), + to_many=True, + has_through_model=( + not field.rel.through._meta.auto_created + ) + ) + + # Deal with reverse relationships. + reverse_relations = SortedDict() + for relation in opts.get_all_related_objects(): + accessor_name = relation.get_accessor_name() + reverse_relations[accessor_name] = RelationInfo( + field=None, + related=relation.model, + to_many=relation.field.rel.multiple, + has_through_model=False + ) + + # Deal with reverse many-to-many relationships. + for relation in opts.get_all_related_many_to_many_objects(): + accessor_name = relation.get_accessor_name() + reverse_relations[accessor_name] = RelationInfo( + field=None, + related=relation.model, + to_many=True, + has_through_model=( + hasattr(relation.field.rel, 'through') and + not relation.field.rel.through._meta.auto_created + ) + ) + + return FieldInfo(pk, fields, forward_relations, reverse_relations) diff --git a/rest_framework/utils/modelinfo.py b/rest_framework/utils/modelinfo.py deleted file mode 100644 index 960fa4d0..00000000 --- a/rest_framework/utils/modelinfo.py +++ /dev/null @@ -1,99 +0,0 @@ -""" -Helper functions for returning the field information that is associated -with a model class. This includes returning all the forward and reverse -relationships and their associated metadata. -""" -from collections import namedtuple -from django.db import models -from django.utils import six -from django.utils.datastructures import SortedDict -import inspect - -FieldInfo = namedtuple('FieldResult', ['pk', 'fields', 'forward_relations', 'reverse_relations']) -RelationInfo = namedtuple('RelationInfo', ['field', 'related', 'to_many', 'has_through_model']) - - -def _resolve_model(obj): - """ - Resolve supplied `obj` to a Django model class. - - `obj` must be a Django model class itself, or a string - representation of one. Useful in situtations like GH #1225 where - Django may not have resolved a string-based reference to a model in - another model's foreign key definition. - - String representations should have the format: - 'appname.ModelName' - """ - if isinstance(obj, six.string_types) and len(obj.split('.')) == 2: - app_name, model_name = obj.split('.') - return models.get_model(app_name, model_name) - elif inspect.isclass(obj) and issubclass(obj, models.Model): - return obj - raise ValueError("{0} is not a Django model".format(obj)) - - -def get_field_info(model): - """ - Given a model class, returns a `FieldInfo` instance containing metadata - about the various field types on the model. - """ - opts = model._meta.concrete_model._meta - - # Deal with the primary key. - pk = opts.pk - while pk.rel and pk.rel.parent_link: - # If model is a child via multitable inheritance, use parent's pk. - pk = pk.rel.to._meta.pk - - # Deal with regular fields. - fields = SortedDict() - for field in [field for field in opts.fields if field.serialize and not field.rel]: - fields[field.name] = field - - # Deal with forward relationships. - forward_relations = SortedDict() - for field in [field for field in opts.fields if field.serialize and field.rel]: - forward_relations[field.name] = RelationInfo( - field=field, - related=_resolve_model(field.rel.to), - to_many=False, - has_through_model=False - ) - - # Deal with forward many-to-many relationships. - for field in [field for field in opts.many_to_many if field.serialize]: - forward_relations[field.name] = RelationInfo( - field=field, - related=_resolve_model(field.rel.to), - to_many=True, - has_through_model=( - not field.rel.through._meta.auto_created - ) - ) - - # Deal with reverse relationships. - reverse_relations = SortedDict() - for relation in opts.get_all_related_objects(): - accessor_name = relation.get_accessor_name() - reverse_relations[accessor_name] = RelationInfo( - field=None, - related=relation.model, - to_many=relation.field.rel.multiple, - has_through_model=False - ) - - # Deal with reverse many-to-many relationships. - for relation in opts.get_all_related_many_to_many_objects(): - accessor_name = relation.get_accessor_name() - reverse_relations[accessor_name] = RelationInfo( - field=None, - related=relation.model, - to_many=True, - has_through_model=( - hasattr(relation.field.rel, 'through') and - not relation.field.rel.through._meta.auto_created - ) - ) - - return FieldInfo(pk, fields, forward_relations, reverse_relations) -- cgit v1.2.3