diff options
| author | Tom Christie | 2013-04-17 09:26:34 +0100 |
|---|---|---|
| committer | Tom Christie | 2013-04-17 09:26:34 +0100 |
| commit | bcf4cb2b4e2fdf10b0df01ece1aa8ce9dc97285a (patch) | |
| tree | 2a27a61091e6be47d9596bdced5976cfbd130576 /rest_framework/serializers.py | |
| parent | ea55143a2308b396c8df6f59a0f6d663c1067163 (diff) | |
| parent | 76e039d70e8fc7f1d5c65180cb544abab81e600e (diff) | |
| download | django-rest-framework-bcf4cb2b4e2fdf10b0df01ece1aa8ce9dc97285a.tar.bz2 | |
Merge branch 'include_reverse_relations' of https://github.com/tomchristie/django-rest-framework into include_reverse_relations
Diffstat (limited to 'rest_framework/serializers.py')
| -rw-r--r-- | rest_framework/serializers.py | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index e28bbe81..eac909c7 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -598,6 +598,24 @@ class ModelSerializer(Serializer): if field: ret[model_field.name] = field + # Reverse relationships are only included if they are explicitly + # present in `Meta.fields`. + if self.opts.fields: + reverse = opts.get_all_related_objects() + reverse += opts.get_all_related_many_to_many_objects() + for rel in reverse: + name = rel.get_accessor_name() + if name not in self.opts.fields: + continue + + if nested: + field = self.get_nested_field(None, rel) + else: + field = self.get_related_field(None, rel, to_many=True) + + if field: + ret[name] = field + for field_name in self.opts.read_only_fields: assert field_name in ret, \ "read_only_fields on '%s' included invalid item '%s'" % \ @@ -612,24 +630,36 @@ class ModelSerializer(Serializer): """ return self.get_field(model_field) - def get_nested_field(self, model_field): + def get_nested_field(self, model_field, rel=None): """ Creates a default instance of a nested relational field. """ + if rel: + model_class = rel.model + else: + model_class = model_field.rel.to + class NestedModelSerializer(ModelSerializer): class Meta: - model = model_field.rel.to + model = model_class return NestedModelSerializer() - def get_related_field(self, model_field, to_many=False): + def get_related_field(self, model_field, rel=None, to_many=False): """ Creates a default instance of a flat relational field. """ # TODO: filter queryset using: # .using(db).complex_filter(self.rel.limit_choices_to) + if rel: + model_class = rel.model + required = True + else: + model_class = model_field.rel.to + required = not(model_field.null or model_field.blank) + kwargs = { - 'required': not(model_field.null or model_field.blank), - 'queryset': model_field.rel.to._default_manager, + 'required': required, + 'queryset': model_class._default_manager, 'many': to_many } @@ -797,7 +827,8 @@ class HyperlinkedModelSerializer(ModelSerializer): return self._default_view_name % format_kwargs def get_pk_field(self, model_field): - return None + if self.opts.fields and model_field.name in self.opts.fields: + return self.get_field(model_field) def get_related_field(self, model_field, to_many): """ |
