diff options
| -rw-r--r-- | docs/api-guide/serializers.md | 37 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 12 | 
2 files changed, 24 insertions, 25 deletions
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index fff03241..47958fe3 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -120,7 +120,7 @@ Let's look at an example of serializing a class that represents an RGB color val              assert(red < 256 and green < 256 and blue < 256)              self.red, self.green, self.blue = red, green, blue -    class ColourField(Field): +    class ColourField(serializers.WritableField):          """          Color objects are serialized into "rgb(#, #, #)" notation.          """ @@ -138,7 +138,7 @@ By default field values are treated as mapping to an attribute on the object.  I  As an example, let's create a field that can be used represent the class name of the object being serialized: -    class ClassNameField(Field): +    class ClassNameField(serializers.WritableField):          def field_to_native(self, obj, field_name):              """              Serialize the object's class name, not an attribute of the object. @@ -158,7 +158,7 @@ As an example, let's create a field that can be used represent the class name of  Often you'll want serializer classes that map closely to model definitions.  The `ModelSerializer` class lets you automatically create a Serializer class with fields that corrospond to the Model fields. -    class AccountSerializer(ModelSerializer): +    class AccountSerializer(serializers.ModelSerializer):          class Meta:              model = Account @@ -168,7 +168,7 @@ The `ModelSerializer` class lets you automatically create a Serializer class wit  You can add extra fields to a `ModelSerializer` or override the default fields by declaring fields on the class, just as you would for a `Serializer` class. -    class AccountSerializer(ModelSerializer): +    class AccountSerializer(serializers.ModelSerializer):          url = CharField(source='get_absolute_url', readonly=True)          group = NaturalKeyField() @@ -183,7 +183,7 @@ When serializing model instances, there are a number of different ways you might  Alternative representations include serializing using natural keys, serializing complete nested representations, or serializing using a custom representation, such as a URL that uniquely identifies the model instances. -The `PrimaryKeyField` and `NaturalKeyField` fields provide alternative flat representations. +The `PrimaryKeyRelatedField` and `HyperlinkedRelatedField` fields provide alternative flat representations.  The `ModelSerializer` class can itself be used as a field, in order to serialize relationships using nested representations. @@ -197,20 +197,16 @@ If you only want a subset of the default fields to be used in a model serializer  For example: -    class AccountSerializer(ModelSerializer): +    class AccountSerializer(serializers.ModelSerializer):          class Meta:              model = Account              exclude = ('id',) -The `fields` and `exclude` options may also be set by passing them to the `serialize()` method. - -**[TODO: Possibly only allow .serialize(fields=…) in FixtureSerializer for backwards compatability, but remove for ModelSerializer]** -  ## Specifiying nested serialization  The default `ModelSerializer` uses primary keys for relationships, but you can also easily generate nested representations using the `nested` option: -    class AccountSerializer(ModelSerializer): +    class AccountSerializer(serializers.ModelSerializer):          class Meta:              model = Account              exclude = ('id',) @@ -220,27 +216,28 @@ The `nested` option may be set to either `True`, `False`, or an integer value.  When serializing objects using a nested representation any occurances of recursion will be recognised, and will fall back to using a flat representation. -The `nested` option may also be set by passing it to the `serialize()` method. +## Customising the default fields used by a ModelSerializer -**[TODO: Possibly only allow .serialize(nested=…) in FixtureSerializer]** -## Customising the default fields used by a ModelSerializer -    class AccountSerializer(ModelSerializer): +    class AccountSerializer(serializers.ModelSerializer):          class Meta:              model = Account          def get_pk_field(self, model_field): -            return Field(readonly=True) +            return serializers.Field(readonly=True)          def get_nested_field(self, model_field): -            return ModelSerializer() +            return serializers.ModelSerializer() -        def get_related_field(self, model_field): -            return NaturalKeyField() +        def get_related_field(self, model_field, to_many=False): +            queryset = model_field.rel.to._default_manager +            if to_many: +                return return serializers.ManyRelatedField(queryset=queryset) +            return serializers.RelatedField(queryset=queryset)          def get_field(self, model_field): -            return Field() +            return serializers.ModelField(model_field=model_field)  [cite]: https://groups.google.com/d/topic/django-users/sVFaOfQi4wY/discussion diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 2141619f..0faad703 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -323,7 +323,9 @@ class ModelSerializer(Serializer):              elif model_field.rel and nested:                  field = self.get_nested_field(model_field)              elif model_field.rel: -                field = self.get_related_field(model_field) +                to_many = isinstance(model_field, +                                     models.fields.related.ManyToManyField) +                field = self.get_related_field(model_field, to_many=to_many)              else:                  field = self.get_field(model_field) @@ -345,14 +347,14 @@ class ModelSerializer(Serializer):          """          return ModelSerializer() -    def get_related_field(self, model_field): +    def get_related_field(self, model_field, 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)          queryset = model_field.rel.to._default_manager -        if isinstance(model_field, models.fields.related.ManyToManyField): +        if to_many:              return ManyPrimaryKeyRelatedField(queryset=queryset)          return PrimaryKeyRelatedField(queryset=queryset) @@ -446,7 +448,7 @@ class HyperlinkedModelSerializer(ModelSerializer):      def get_pk_field(self, model_field):          return None -    def get_related_field(self, model_field): +    def get_related_field(self, model_field, to_many):          """          Creates a default instance of a flat relational field.          """ @@ -458,6 +460,6 @@ class HyperlinkedModelSerializer(ModelSerializer):              'queryset': queryset,              'view_name': self._get_default_view_name(rel)          } -        if isinstance(model_field, models.fields.related.ManyToManyField): +        if to_many:              return ManyHyperlinkedRelatedField(**kwargs)          return HyperlinkedRelatedField(**kwargs)  | 
