From 670723f0216e5aea3aa133c99703949900be3d20 Mon Sep 17 00:00:00 2001
From: Tom Christie <tom@tomchristie.com>
Date: Fri, 6 Feb 2015 15:45:02 +0000
Subject: [PATCH] Minor cleanups/improvements to ModelSerializer API

---
 docs/api-guide/serializers.md | 20 ++++++++++++++++++--
 rest_framework/serializers.py | 15 +++++++++------
 2 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index 9a9d5032d..940eb4249 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -577,9 +577,25 @@ Normally if a `ModelSerializer` does not generate the fields you need by default
 
 A mapping of Django model classes to REST framework serializer classes. You can override this mapping to alter the default serializer classes that should be used for each model class.
 
-### `.serializer_relational_field`
+### `.serializer_related_field`
 
-This property should be the serializer field class, that is used for relational fields by default. For `ModelSerializer` this defaults to `PrimaryKeyRelatedField`. For `HyperlinkedModelSerializer` this defaults to `HyperlinkedRelatedField`.
+This property should be the serializer field class, that is used for relational fields by default.
+
+For `ModelSerializer` this defaults to `PrimaryKeyRelatedField`.
+
+For `HyperlinkedModelSerializer` this defaults to `serializers.HyperlinkedRelatedField`.
+
+### `serializer_url_field`
+
+The serializer field class that should be used for any `url` field on the serializer.
+
+Defaults to `serializers.HyperlinkedIdentityField`
+
+### `serializer_choice_field`
+
+The serializer field class that should be used for any choice fields on the serializer.
+
+Defaults to `serializers.ChoiceField`
 
 ### The field_class and field_kwargs API
 
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 18b810dfe..7f3fd078c 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -728,7 +728,9 @@ class ModelSerializer(Serializer):
         models.TimeField: TimeField,
         models.URLField: URLField,
     }
-    serializer_related_class = PrimaryKeyRelatedField
+    serializer_related_field = PrimaryKeyRelatedField
+    serializer_url_field = HyperlinkedIdentityField
+    serializer_choice_field = ChoiceField
 
     # Default `create` and `update` behavior...
 
@@ -985,7 +987,7 @@ class ModelSerializer(Serializer):
         if 'choices' in field_kwargs:
             # Fields with choices get coerced into `ChoiceField`
             # instead of using their regular typed field.
-            field_class = ChoiceField
+            field_class = self.serializer_choice_field
 
         if not issubclass(field_class, ModelField):
             # `model_field` is only valid for the fallback case of
@@ -998,11 +1000,12 @@ class ModelSerializer(Serializer):
             field_kwargs.pop('allow_blank', None)
 
         if postgres_fields and isinstance(model_field, postgres_fields.ArrayField):
+            # Populate the `child` argument on `ListField` instances generated
+            # for the PostgrSQL specfic `ArrayField`.
             child_model_field = model_field.base_field
             child_field_class, child_field_kwargs = self.build_standard_field(
                 'child', child_model_field
             )
-
             field_kwargs['child'] = child_field_class(**child_field_kwargs)
 
         return field_class, field_kwargs
@@ -1011,7 +1014,7 @@ class ModelSerializer(Serializer):
         """
         Create fields for forward and reverse relationships.
         """
-        field_class = self.serializer_related_class
+        field_class = self.serializer_related_field
         field_kwargs = get_relation_kwargs(field_name, relation_info)
 
         # `view_name` is only valid for hyperlinked relationships.
@@ -1047,7 +1050,7 @@ class ModelSerializer(Serializer):
         """
         Create a field representing the object's own URL.
         """
-        field_class = HyperlinkedIdentityField
+        field_class = self.serializer_url_field
         field_kwargs = get_url_kwargs(model_class)
 
         return field_class, field_kwargs
@@ -1358,7 +1361,7 @@ class HyperlinkedModelSerializer(ModelSerializer):
     * A 'url' field is included instead of the 'id' field.
     * Relationships to other instances are hyperlinks, instead of primary keys.
     """
-    serializer_related_class = HyperlinkedRelatedField
+    serializer_related_field = HyperlinkedRelatedField
 
     def get_default_field_names(self, declared_fields, model_info):
         """