This commit is contained in:
Lingchuan Xu 2018-09-07 07:43:44 +00:00 committed by GitHub
commit b5dae88da9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -23,13 +23,17 @@ from django.db import models
from django.db.models import DurationField as ModelDurationField from django.db.models import DurationField as ModelDurationField
from django.db.models.fields import Field as DjangoModelField from django.db.models.fields import Field as DjangoModelField
from django.db.models.fields import FieldDoesNotExist from django.db.models.fields import FieldDoesNotExist
from django.forms.fields import \
MultipleChoiceField as DjangoFormMultipleChoiceField
from django.utils import six, timezone from django.utils import six, timezone
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework.compat import postgres_fields, unicode_to_repr from rest_framework.compat import postgres_fields, unicode_to_repr
from rest_framework.exceptions import ErrorDetail, ValidationError from rest_framework.exceptions import ErrorDetail, ValidationError
from rest_framework.fields import get_error_detail, set_value from rest_framework.fields import (
MultipleChoiceField, get_error_detail, set_value
)
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
from rest_framework.utils import html, model_meta, representation from rest_framework.utils import html, model_meta, representation
from rest_framework.utils.field_mapping import ( from rest_framework.utils.field_mapping import (
@ -1208,7 +1212,17 @@ class ModelSerializer(Serializer):
if 'choices' in field_kwargs: if 'choices' in field_kwargs:
# Fields with choices get coerced into `ChoiceField` # Fields with choices get coerced into `ChoiceField`
# instead of using their regular typed field. # instead of using their regular typed field.
field_class = self.serializer_choice_field # And also check if `MultipleChoiceField` is needed.
field_defined_as_multiple = getattr(model_field, 'serializer_multiple_choices', None)
is_multi_choice = bool(field_defined_as_multiple)
if field_defined_as_multiple is None:
# Check formfield if this field uses multiple choices as default.
try:
model_field_class = model_field.formfield()
is_multi_choice = isinstance(model_field_class, (DjangoFormMultipleChoiceField, ))
except TypeError:
pass
field_class = self.serializer_choice_field if not is_multi_choice else MultipleChoiceField
# Some model fields may introduce kwargs that would not be valid # Some model fields may introduce kwargs that would not be valid
# for the choice field. We need to strip these out. # for the choice field. We need to strip these out.
# Eg. models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES) # Eg. models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES)
@ -1252,7 +1266,8 @@ class ModelSerializer(Serializer):
field_kwargs = get_relation_kwargs(field_name, relation_info) field_kwargs = get_relation_kwargs(field_name, relation_info)
to_field = field_kwargs.pop('to_field', None) to_field = field_kwargs.pop('to_field', None)
if to_field and not relation_info.reverse and not relation_info.related_model._meta.get_field(to_field).primary_key: if (to_field and not relation_info.reverse and
not relation_info.related_model._meta.get_field(to_field).primary_key):
field_kwargs['slug_field'] = to_field field_kwargs['slug_field'] = to_field
field_class = self.serializer_related_to_field field_class = self.serializer_related_to_field