1"""
2Serializers and ModelSerializers are similar to Forms and ModelForms.
3Unlike forms, they are not constrained to dealing with HTML output, and
4form encoded input.
5
6Serialization in REST framework is a two-phase process:
7
81. Serializers marshal between complex types like model instances, and
9python primitives.
102. The process of marshalling between python primitives and request and
11response content is handled by parsers and renderers.
12"""
13import copy
14import inspect
15import traceback
16from collections import OrderedDict, defaultdict
17from collections.abc import Mapping
18
19from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
20from django.core.exceptions import ValidationError as DjangoValidationError
21from django.db import models
22from django.db.models.fields import Field as DjangoModelField
23from django.utils import timezone
24from django.utils.functional import cached_property
25from django.utils.translation import gettext_lazy as _
26
27from rest_framework.compat import postgres_fields
28from rest_framework.exceptions import ErrorDetail, ValidationError
29from rest_framework.fields import get_error_detail, set_value
30from rest_framework.settings import api_settings
31from rest_framework.utils import html, model_meta, representation
32from rest_framework.utils.field_mapping import (
33    ClassLookupDict, get_field_kwargs, get_nested_relation_kwargs,
34    get_relation_kwargs, get_url_kwargs
35)
36from rest_framework.utils.serializer_helpers import (
37    BindingDict, BoundField, JSONBoundField, NestedBoundField, ReturnDict,
38    ReturnList
39)
40from rest_framework.validators import (
41    UniqueForDateValidator, UniqueForMonthValidator, UniqueForYearValidator,
42    UniqueTogetherValidator
43)
44
45# Note: We do the following so that users of the framework can use this style:
46#
47#     example_field = serializers.CharField(...)
48#
49# This helps keep the separation between model fields, form fields, and
50# serializer fields more explicit.
51from rest_framework.fields import (  # NOQA # isort:skip
52    BooleanField, CharField, ChoiceField, DateField, DateTimeField, DecimalField,
53    DictField, DurationField, EmailField, Field, FileField, FilePathField, FloatField,
54    HiddenField, HStoreField, IPAddressField, ImageField, IntegerField, JSONField,
55    ListField, ModelField, MultipleChoiceField, NullBooleanField, ReadOnlyField,
56    RegexField, SerializerMethodField, SlugField, TimeField, URLField, UUIDField,
57)
58from rest_framework.relations import (  # NOQA # isort:skip
59    HyperlinkedIdentityField, HyperlinkedRelatedField, ManyRelatedField,
60    PrimaryKeyRelatedField, RelatedField, SlugRelatedField, StringRelatedField,
61)
62
63# Non-field imports, but public API
64from rest_framework.fields import (  # NOQA # isort:skip
65    CreateOnlyDefault, CurrentUserDefault, SkipField, empty
66)
67from rest_framework.relations import Hyperlink, PKOnlyObject  # NOQA # isort:skip
68
69# We assume that 'validators' are intended for the child serializer,
70# rather than the parent serializer.
71LIST_SERIALIZER_KWARGS = (
72    'read_only', 'write_only', 'required', 'default', 'initial', 'source',
73    'label', 'help_text', 'style', 'error_messages', 'allow_empty',
74    'instance', 'data', 'partial', 'context', 'allow_null'
75)
76
77ALL_FIELDS = '__all__'
78
79
80# BaseSerializer
81# --------------
82
83class BaseSerializer(Field):
84    """
85    The BaseSerializer class provides a minimal class which may be used
86    for writing custom serializer implementations.
87
88    Note that we strongly restrict the ordering of operations/properties
89    that may be used on the serializer in order to enforce correct usage.
90
91    In particular, if a `data=` argument is passed then:
92
93    .is_valid() - Available.
94    .initial_data - Available.
95    .validated_data - Only available after calling `is_valid()`
96    .errors - Only available after calling `is_valid()`
97    .data - Only available after calling `is_valid()`
98
99    If a `data=` argument is not passed then:
100
101    .is_valid() - Not available.
102    .initial_data - Not available.
103    .validated_data - Not available.
104    .errors - Not available.
105    .data - Available.
106    """
107
108    def __init__(self, instance=None, data=empty, **kwargs):
109        self.instance = instance
110        if data is not empty:
111            self.initial_data = data
112        self.partial = kwargs.pop('partial', False)
113        self._context = kwargs.pop('context', {})
114        kwargs.pop('many', None)
115        super().__init__(**kwargs)
116
117    def __new__(cls, *args, **kwargs):
118        # We override this method in order to automatically create
119        # `ListSerializer` classes instead when `many=True` is set.
120        if kwargs.pop('many', False):
121            return cls.many_init(*args, **kwargs)
122        return super().__new__(cls, *args, **kwargs)
123
124    # Allow type checkers to make serializers generic.
125    def __class_getitem__(cls, *args, **kwargs):
126        return cls
127
128    @classmethod
129    def many_init(cls, *args, **kwargs):
130        """
131        This method implements the creation of a `ListSerializer` parent
132        class when `many=True` is used. You can customize it if you need to
133        control which keyword arguments are passed to the parent, and
134        which are passed to the child.
135
136        Note that we're over-cautious in passing most arguments to both parent
137        and child classes in order to try to cover the general case. If you're
138        overriding this method you'll probably want something much simpler, eg:
139
140        @classmethod
141        def many_init(cls, *args, **kwargs):
142            kwargs['child'] = cls()
143            return CustomListSerializer(*args, **kwargs)
144        """
145        allow_empty = kwargs.pop('allow_empty', None)
146        child_serializer = cls(*args, **kwargs)
147        list_kwargs = {
148            'child': child_serializer,
149        }
150        if allow_empty is not None:
151            list_kwargs['allow_empty'] = allow_empty
152        list_kwargs.update({
153            key: value for key, value in kwargs.items()
154            if key in LIST_SERIALIZER_KWARGS
155        })
156        meta = getattr(cls, 'Meta', None)
157        list_serializer_class = getattr(meta, 'list_serializer_class', ListSerializer)
158        return list_serializer_class(*args, **list_kwargs)
159
160    def to_internal_value(self, data):
161        raise NotImplementedError('`to_internal_value()` must be implemented.')
162
163    def to_representation(self, instance):
164        raise NotImplementedError('`to_representation()` must be implemented.')
165
166    def update(self, instance, validated_data):
167        raise NotImplementedError('`update()` must be implemented.')
168
169    def create(self, validated_data):
170        raise NotImplementedError('`create()` must be implemented.')
171
172    def save(self, **kwargs):
173        assert hasattr(self, '_errors'), (
174            'You must call `.is_valid()` before calling `.save()`.'
175        )
176
177        assert not self.errors, (
178            'You cannot call `.save()` on a serializer with invalid data.'
179        )
180
181        # Guard against incorrect use of `serializer.save(commit=False)`
182        assert 'commit' not in kwargs, (
183            "'commit' is not a valid keyword argument to the 'save()' method. "
184            "If you need to access data before committing to the database then "
185            "inspect 'serializer.validated_data' instead. "
186            "You can also pass additional keyword arguments to 'save()' if you "
187            "need to set extra attributes on the saved model instance. "
188            "For example: 'serializer.save(owner=request.user)'.'"
189        )
190
191        assert not hasattr(self, '_data'), (
192            "You cannot call `.save()` after accessing `serializer.data`."
193            "If you need to access data before committing to the database then "
194            "inspect 'serializer.validated_data' instead. "
195        )
196
197        validated_data = {**self.validated_data, **kwargs}
198
199        if self.instance is not None:
200            self.instance = self.update(self.instance, validated_data)
201            assert self.instance is not None, (
202                '`update()` did not return an object instance.'
203            )
204        else:
205            self.instance = self.create(validated_data)
206            assert self.instance is not None, (
207                '`create()` did not return an object instance.'
208            )
209
210        return self.instance
211
212    def is_valid(self, raise_exception=False):
213        assert hasattr(self, 'initial_data'), (
214            'Cannot call `.is_valid()` as no `data=` keyword argument was '
215            'passed when instantiating the serializer instance.'
216        )
217
218        if not hasattr(self, '_validated_data'):
219            try:
220                self._validated_data = self.run_validation(self.initial_data)
221            except ValidationError as exc:
222                self._validated_data = {}
223                self._errors = exc.detail
224            else:
225                self._errors = {}
226
227        if self._errors and raise_exception:
228            raise ValidationError(self.errors)
229
230        return not bool(self._errors)
231
232    @property
233    def data(self):
234        if hasattr(self, 'initial_data') and not hasattr(self, '_validated_data'):
235            msg = (
236                'When a serializer is passed a `data` keyword argument you '
237                'must call `.is_valid()` before attempting to access the '
238                'serialized `.data` representation.\n'
239                'You should either call `.is_valid()` first, '
240                'or access `.initial_data` instead.'
241            )
242            raise AssertionError(msg)
243
244        if not hasattr(self, '_data'):
245            if self.instance is not None and not getattr(self, '_errors', None):
246                self._data = self.to_representation(self.instance)
247            elif hasattr(self, '_validated_data') and not getattr(self, '_errors', None):
248                self._data = self.to_representation(self.validated_data)
249            else:
250                self._data = self.get_initial()
251        return self._data
252
253    @property
254    def errors(self):
255        if not hasattr(self, '_errors'):
256            msg = 'You must call `.is_valid()` before accessing `.errors`.'
257            raise AssertionError(msg)
258        return self._errors
259
260    @property
261    def validated_data(self):
262        if not hasattr(self, '_validated_data'):
263            msg = 'You must call `.is_valid()` before accessing `.validated_data`.'
264            raise AssertionError(msg)
265        return self._validated_data
266
267
268# Serializer & ListSerializer classes
269# -----------------------------------
270
271class SerializerMetaclass(type):
272    """
273    This metaclass sets a dictionary named `_declared_fields` on the class.
274
275    Any instances of `Field` included as attributes on either the class
276    or on any of its superclasses will be include in the
277    `_declared_fields` dictionary.
278    """
279
280    @classmethod
281    def _get_declared_fields(cls, bases, attrs):
282        fields = [(field_name, attrs.pop(field_name))
283                  for field_name, obj in list(attrs.items())
284                  if isinstance(obj, Field)]
285        fields.sort(key=lambda x: x[1]._creation_counter)
286
287        # Ensures a base class field doesn't override cls attrs, and maintains
288        # field precedence when inheriting multiple parents. e.g. if there is a
289        # class C(A, B), and A and B both define 'field', use 'field' from A.
290        known = set(attrs)
291
292        def visit(name):
293            known.add(name)
294            return name
295
296        base_fields = [
297            (visit(name), f)
298            for base in bases if hasattr(base, '_declared_fields')
299            for name, f in base._declared_fields.items() if name not in known
300        ]
301
302        return OrderedDict(base_fields + fields)
303
304    def __new__(cls, name, bases, attrs):
305        attrs['_declared_fields'] = cls._get_declared_fields(bases, attrs)
306        return super().__new__(cls, name, bases, attrs)
307
308
309def as_serializer_error(exc):
310    assert isinstance(exc, (ValidationError, DjangoValidationError))
311
312    if isinstance(exc, DjangoValidationError):
313        detail = get_error_detail(exc)
314    else:
315        detail = exc.detail
316
317    if isinstance(detail, Mapping):
318        # If errors may be a dict we use the standard {key: list of values}.
319        # Here we ensure that all the values are *lists* of errors.
320        return {
321            key: value if isinstance(value, (list, Mapping)) else [value]
322            for key, value in detail.items()
323        }
324    elif isinstance(detail, list):
325        # Errors raised as a list are non-field errors.
326        return {
327            api_settings.NON_FIELD_ERRORS_KEY: detail
328        }
329    # Errors raised as a string are non-field errors.
330    return {
331        api_settings.NON_FIELD_ERRORS_KEY: [detail]
332    }
333
334
335class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
336    default_error_messages = {
337        'invalid': _('Invalid data. Expected a dictionary, but got {datatype}.')
338    }
339
340    @cached_property
341    def fields(self):
342        """
343        A dictionary of {field_name: field_instance}.
344        """
345        # `fields` is evaluated lazily. We do this to ensure that we don't
346        # have issues importing modules that use ModelSerializers as fields,
347        # even if Django's app-loading stage has not yet run.
348        fields = BindingDict(self)
349        for key, value in self.get_fields().items():
350            fields[key] = value
351        return fields
352
353    @property
354    def _writable_fields(self):
355        for field in self.fields.values():
356            if not field.read_only:
357                yield field
358
359    @property
360    def _readable_fields(self):
361        for field in self.fields.values():
362            if not field.write_only:
363                yield field
364
365    def get_fields(self):
366        """
367        Returns a dictionary of {field_name: field_instance}.
368        """
369        # Every new serializer is created with a clone of the field instances.
370        # This allows users to dynamically modify the fields on a serializer
371        # instance without affecting every other serializer instance.
372        return copy.deepcopy(self._declared_fields)
373
374    def get_validators(self):
375        """
376        Returns a list of validator callables.
377        """
378        # Used by the lazily-evaluated `validators` property.
379        meta = getattr(self, 'Meta', None)
380        validators = getattr(meta, 'validators', None)
381        return list(validators) if validators else []
382
383    def get_initial(self):
384        if hasattr(self, 'initial_data'):
385            # initial_data may not be a valid type
386            if not isinstance(self.initial_data, Mapping):
387                return OrderedDict()
388
389            return OrderedDict([
390                (field_name, field.get_value(self.initial_data))
391                for field_name, field in self.fields.items()
392                if (field.get_value(self.initial_data) is not empty) and
393                not field.read_only
394            ])
395
396        return OrderedDict([
397            (field.field_name, field.get_initial())
398            for field in self.fields.values()
399            if not field.read_only
400        ])
401
402    def get_value(self, dictionary):
403        # We override the default field access in order to support
404        # nested HTML forms.
405        if html.is_html_input(dictionary):
406            return html.parse_html_dict(dictionary, prefix=self.field_name) or empty
407        return dictionary.get(self.field_name, empty)
408
409    def run_validation(self, data=empty):
410        """
411        We override the default `run_validation`, because the validation
412        performed by validators and the `.validate()` method should
413        be coerced into an error dictionary with a 'non_fields_error' key.
414        """
415        (is_empty_value, data) = self.validate_empty_values(data)
416        if is_empty_value:
417            return data
418
419        value = self.to_internal_value(data)
420        try:
421            self.run_validators(value)
422            value = self.validate(value)
423            assert value is not None, '.validate() should return the validated data'
424        except (ValidationError, DjangoValidationError) as exc:
425            raise ValidationError(detail=as_serializer_error(exc))
426
427        return value
428
429    def _read_only_defaults(self):
430        fields = [
431            field for field in self.fields.values()
432            if (field.read_only) and (field.default != empty) and (field.source != '*') and ('.' not in field.source)
433        ]
434
435        defaults = OrderedDict()
436        for field in fields:
437            try:
438                default = field.get_default()
439            except SkipField:
440                continue
441            defaults[field.source] = default
442
443        return defaults
444
445    def run_validators(self, value):
446        """
447        Add read_only fields with defaults to value before running validators.
448        """
449        if isinstance(value, dict):
450            to_validate = self._read_only_defaults()
451            to_validate.update(value)
452        else:
453            to_validate = value
454        super().run_validators(to_validate)
455
456    def to_internal_value(self, data):
457        """
458        Dict of native values <- Dict of primitive datatypes.
459        """
460        if not isinstance(data, Mapping):
461            message = self.error_messages['invalid'].format(
462                datatype=type(data).__name__
463            )
464            raise ValidationError({
465                api_settings.NON_FIELD_ERRORS_KEY: [message]
466            }, code='invalid')
467
468        ret = OrderedDict()
469        errors = OrderedDict()
470        fields = self._writable_fields
471
472        for field in fields:
473            validate_method = getattr(self, 'validate_' + field.field_name, None)
474            primitive_value = field.get_value(data)
475            try:
476                validated_value = field.run_validation(primitive_value)
477                if validate_method is not None:
478                    validated_value = validate_method(validated_value)
479            except ValidationError as exc:
480                errors[field.field_name] = exc.detail
481            except DjangoValidationError as exc:
482                errors[field.field_name] = get_error_detail(exc)
483            except SkipField:
484                pass
485            else:
486                set_value(ret, field.source_attrs, validated_value)
487
488        if errors:
489            raise ValidationError(errors)
490
491        return ret
492
493    def to_representation(self, instance):
494        """
495        Object instance -> Dict of primitive datatypes.
496        """
497        ret = OrderedDict()
498        fields = self._readable_fields
499
500        for field in fields:
501            try:
502                attribute = field.get_attribute(instance)
503            except SkipField:
504                continue
505
506            # We skip `to_representation` for `None` values so that fields do
507            # not have to explicitly deal with that case.
508            #
509            # For related fields with `use_pk_only_optimization` we need to
510            # resolve the pk value.
511            check_for_none = attribute.pk if isinstance(attribute, PKOnlyObject) else attribute
512            if check_for_none is None:
513                ret[field.field_name] = None
514            else:
515                ret[field.field_name] = field.to_representation(attribute)
516
517        return ret
518
519    def validate(self, attrs):
520        return attrs
521
522    def __repr__(self):
523        return representation.serializer_repr(self, indent=1)
524
525    # The following are used for accessing `BoundField` instances on the
526    # serializer, for the purposes of presenting a form-like API onto the
527    # field values and field errors.
528
529    def __iter__(self):
530        for field in self.fields.values():
531            yield self[field.field_name]
532
533    def __getitem__(self, key):
534        field = self.fields[key]
535        value = self.data.get(key)
536        error = self.errors.get(key) if hasattr(self, '_errors') else None
537        if isinstance(field, Serializer):
538            return NestedBoundField(field, value, error)
539        if isinstance(field, JSONField):
540            return JSONBoundField(field, value, error)
541        return BoundField(field, value, error)
542
543    # Include a backlink to the serializer class on return objects.
544    # Allows renderers such as HTMLFormRenderer to get the full field info.
545
546    @property
547    def data(self):
548        ret = super().data
549        return ReturnDict(ret, serializer=self)
550
551    @property
552    def errors(self):
553        ret = super().errors
554        if isinstance(ret, list) and len(ret) == 1 and getattr(ret[0], 'code', None) == 'null':
555            # Edge case. Provide a more descriptive error than
556            # "this field may not be null", when no data is passed.
557            detail = ErrorDetail('No data provided', code='null')
558            ret = {api_settings.NON_FIELD_ERRORS_KEY: [detail]}
559        return ReturnDict(ret, serializer=self)
560
561
562# There's some replication of `ListField` here,
563# but that's probably better than obfuscating the call hierarchy.
564
565class ListSerializer(BaseSerializer):
566    child = None
567    many = True
568
569    default_error_messages = {
570        'not_a_list': _('Expected a list of items but got type "{input_type}".'),
571        'empty': _('This list may not be empty.')
572    }
573
574    def __init__(self, *args, **kwargs):
575        self.child = kwargs.pop('child', copy.deepcopy(self.child))
576        self.allow_empty = kwargs.pop('allow_empty', True)
577        assert self.child is not None, '`child` is a required argument.'
578        assert not inspect.isclass(self.child), '`child` has not been instantiated.'
579        super().__init__(*args, **kwargs)
580        self.child.bind(field_name='', parent=self)
581
582    def get_initial(self):
583        if hasattr(self, 'initial_data'):
584            return self.to_representation(self.initial_data)
585        return []
586
587    def get_value(self, dictionary):
588        """
589        Given the input dictionary, return the field value.
590        """
591        # We override the default field access in order to support
592        # lists in HTML forms.
593        if html.is_html_input(dictionary):
594            return html.parse_html_list(dictionary, prefix=self.field_name, default=empty)
595        return dictionary.get(self.field_name, empty)
596
597    def run_validation(self, data=empty):
598        """
599        We override the default `run_validation`, because the validation
600        performed by validators and the `.validate()` method should
601        be coerced into an error dictionary with a 'non_fields_error' key.
602        """
603        (is_empty_value, data) = self.validate_empty_values(data)
604        if is_empty_value:
605            return data
606
607        value = self.to_internal_value(data)
608        try:
609            self.run_validators(value)
610            value = self.validate(value)
611            assert value is not None, '.validate() should return the validated data'
612        except (ValidationError, DjangoValidationError) as exc:
613            raise ValidationError(detail=as_serializer_error(exc))
614
615        return value
616
617    def to_internal_value(self, data):
618        """
619        List of dicts of native values <- List of dicts of primitive datatypes.
620        """
621        if html.is_html_input(data):
622            data = html.parse_html_list(data, default=[])
623
624        if not isinstance(data, list):
625            message = self.error_messages['not_a_list'].format(
626                input_type=type(data).__name__
627            )
628            raise ValidationError({
629                api_settings.NON_FIELD_ERRORS_KEY: [message]
630            }, code='not_a_list')
631
632        if not self.allow_empty and len(data) == 0:
633            message = self.error_messages['empty']
634            raise ValidationError({
635                api_settings.NON_FIELD_ERRORS_KEY: [message]
636            }, code='empty')
637
638        ret = []
639        errors = []
640
641        for item in data:
642            try:
643                validated = self.child.run_validation(item)
644            except ValidationError as exc:
645                errors.append(exc.detail)
646            else:
647                ret.append(validated)
648                errors.append({})
649
650        if any(errors):
651            raise ValidationError(errors)
652
653        return ret
654
655    def to_representation(self, data):
656        """
657        List of object instances -> List of dicts of primitive datatypes.
658        """
659        # Dealing with nested relationships, data can be a Manager,
660        # so, first get a queryset from the Manager if needed
661        iterable = data.all() if isinstance(data, models.Manager) else data
662
663        return [
664            self.child.to_representation(item) for item in iterable
665        ]
666
667    def validate(self, attrs):
668        return attrs
669
670    def update(self, instance, validated_data):
671        raise NotImplementedError(
672            "Serializers with many=True do not support multiple update by "
673            "default, only multiple create. For updates it is unclear how to "
674            "deal with insertions and deletions. If you need to support "
675            "multiple update, use a `ListSerializer` class and override "
676            "`.update()` so you can specify the behavior exactly."
677        )
678
679    def create(self, validated_data):
680        return [
681            self.child.create(attrs) for attrs in validated_data
682        ]
683
684    def save(self, **kwargs):
685        """
686        Save and return a list of object instances.
687        """
688        # Guard against incorrect use of `serializer.save(commit=False)`
689        assert 'commit' not in kwargs, (
690            "'commit' is not a valid keyword argument to the 'save()' method. "
691            "If you need to access data before committing to the database then "
692            "inspect 'serializer.validated_data' instead. "
693            "You can also pass additional keyword arguments to 'save()' if you "
694            "need to set extra attributes on the saved model instance. "
695            "For example: 'serializer.save(owner=request.user)'.'"
696        )
697
698        validated_data = [
699            {**attrs, **kwargs} for attrs in self.validated_data
700        ]
701
702        if self.instance is not None:
703            self.instance = self.update(self.instance, validated_data)
704            assert self.instance is not None, (
705                '`update()` did not return an object instance.'
706            )
707        else:
708            self.instance = self.create(validated_data)
709            assert self.instance is not None, (
710                '`create()` did not return an object instance.'
711            )
712
713        return self.instance
714
715    def is_valid(self, raise_exception=False):
716        # This implementation is the same as the default,
717        # except that we use lists, rather than dicts, as the empty case.
718        assert hasattr(self, 'initial_data'), (
719            'Cannot call `.is_valid()` as no `data=` keyword argument was '
720            'passed when instantiating the serializer instance.'
721        )
722
723        if not hasattr(self, '_validated_data'):
724            try:
725                self._validated_data = self.run_validation(self.initial_data)
726            except ValidationError as exc:
727                self._validated_data = []
728                self._errors = exc.detail
729            else:
730                self._errors = []
731
732        if self._errors and raise_exception:
733            raise ValidationError(self.errors)
734
735        return not bool(self._errors)
736
737    def __repr__(self):
738        return representation.list_repr(self, indent=1)
739
740    # Include a backlink to the serializer class on return objects.
741    # Allows renderers such as HTMLFormRenderer to get the full field info.
742
743    @property
744    def data(self):
745        ret = super().data
746        return ReturnList(ret, serializer=self)
747
748    @property
749    def errors(self):
750        ret = super().errors
751        if isinstance(ret, list) and len(ret) == 1 and getattr(ret[0], 'code', None) == 'null':
752            # Edge case. Provide a more descriptive error than
753            # "this field may not be null", when no data is passed.
754            detail = ErrorDetail('No data provided', code='null')
755            ret = {api_settings.NON_FIELD_ERRORS_KEY: [detail]}
756        if isinstance(ret, dict):
757            return ReturnDict(ret, serializer=self)
758        return ReturnList(ret, serializer=self)
759
760
761# ModelSerializer & HyperlinkedModelSerializer
762# --------------------------------------------
763
764def raise_errors_on_nested_writes(method_name, serializer, validated_data):
765    """
766    Give explicit errors when users attempt to pass writable nested data.
767
768    If we don't do this explicitly they'd get a less helpful error when
769    calling `.save()` on the serializer.
770
771    We don't *automatically* support these sorts of nested writes because
772    there are too many ambiguities to define a default behavior.
773
774    Eg. Suppose we have a `UserSerializer` with a nested profile. How should
775    we handle the case of an update, where the `profile` relationship does
776    not exist? Any of the following might be valid:
777
778    * Raise an application error.
779    * Silently ignore the nested part of the update.
780    * Automatically create a profile instance.
781    """
782    ModelClass = serializer.Meta.model
783    model_field_info = model_meta.get_field_info(ModelClass)
784
785    # Ensure we don't have a writable nested field. For example:
786    #
787    # class UserSerializer(ModelSerializer):
788    #     ...
789    #     profile = ProfileSerializer()
790    assert not any(
791        isinstance(field, BaseSerializer) and
792        (field.source in validated_data) and
793        (field.source in model_field_info.relations) and
794        isinstance(validated_data[field.source], (list, dict))
795        for field in serializer._writable_fields
796    ), (
797        'The `.{method_name}()` method does not support writable nested '
798        'fields by default.\nWrite an explicit `.{method_name}()` method for '
799        'serializer `{module}.{class_name}`, or set `read_only=True` on '
800        'nested serializer fields.'.format(
801            method_name=method_name,
802            module=serializer.__class__.__module__,
803            class_name=serializer.__class__.__name__
804        )
805    )
806
807    # Ensure we don't have a writable dotted-source field. For example:
808    #
809    # class UserSerializer(ModelSerializer):
810    #     ...
811    #     address = serializer.CharField('profile.address')
812    #
813    # Though, non-relational fields (e.g., JSONField) are acceptable. For example:
814    #
815    # class NonRelationalPersonModel(models.Model):
816    #     profile = JSONField()
817    #
818    # class UserSerializer(ModelSerializer):
819    #     ...
820    #     address = serializer.CharField('profile.address')
821    assert not any(
822        len(field.source_attrs) > 1 and
823        (field.source_attrs[0] in validated_data) and
824        (field.source_attrs[0] in model_field_info.relations) and
825        isinstance(validated_data[field.source_attrs[0]], (list, dict))
826        for field in serializer._writable_fields
827    ), (
828        'The `.{method_name}()` method does not support writable dotted-source '
829        'fields by default.\nWrite an explicit `.{method_name}()` method for '
830        'serializer `{module}.{class_name}`, or set `read_only=True` on '
831        'dotted-source serializer fields.'.format(
832            method_name=method_name,
833            module=serializer.__class__.__module__,
834            class_name=serializer.__class__.__name__
835        )
836    )
837
838
839class ModelSerializer(Serializer):
840    """
841    A `ModelSerializer` is just a regular `Serializer`, except that:
842
843    * A set of default fields are automatically populated.
844    * A set of default validators are automatically populated.
845    * Default `.create()` and `.update()` implementations are provided.
846
847    The process of automatically determining a set of serializer fields
848    based on the model fields is reasonably complex, but you almost certainly
849    don't need to dig into the implementation.
850
851    If the `ModelSerializer` class *doesn't* generate the set of fields that
852    you need you should either declare the extra/differing fields explicitly on
853    the serializer class, or simply use a `Serializer` class.
854    """
855    serializer_field_mapping = {
856        models.AutoField: IntegerField,
857        models.BigIntegerField: IntegerField,
858        models.BooleanField: BooleanField,
859        models.CharField: CharField,
860        models.CommaSeparatedIntegerField: CharField,
861        models.DateField: DateField,
862        models.DateTimeField: DateTimeField,
863        models.DecimalField: DecimalField,
864        models.DurationField: DurationField,
865        models.EmailField: EmailField,
866        models.Field: ModelField,
867        models.FileField: FileField,
868        models.FloatField: FloatField,
869        models.ImageField: ImageField,
870        models.IntegerField: IntegerField,
871        models.NullBooleanField: BooleanField,
872        models.PositiveIntegerField: IntegerField,
873        models.PositiveSmallIntegerField: IntegerField,
874        models.SlugField: SlugField,
875        models.SmallIntegerField: IntegerField,
876        models.TextField: CharField,
877        models.TimeField: TimeField,
878        models.URLField: URLField,
879        models.UUIDField: UUIDField,
880        models.GenericIPAddressField: IPAddressField,
881        models.FilePathField: FilePathField,
882    }
883    if hasattr(models, 'JSONField'):
884        serializer_field_mapping[models.JSONField] = JSONField
885    if postgres_fields:
886        serializer_field_mapping[postgres_fields.HStoreField] = HStoreField
887        serializer_field_mapping[postgres_fields.ArrayField] = ListField
888        serializer_field_mapping[postgres_fields.JSONField] = JSONField
889    serializer_related_field = PrimaryKeyRelatedField
890    serializer_related_to_field = SlugRelatedField
891    serializer_url_field = HyperlinkedIdentityField
892    serializer_choice_field = ChoiceField
893
894    # The field name for hyperlinked identity fields. Defaults to 'url'.
895    # You can modify this using the API setting.
896    #
897    # Note that if you instead need modify this on a per-serializer basis,
898    # you'll also need to ensure you update the `create` method on any generic
899    # views, to correctly handle the 'Location' response header for
900    # "HTTP 201 Created" responses.
901    url_field_name = None
902
903    # Default `create` and `update` behavior...
904    def create(self, validated_data):
905        """
906        We have a bit of extra checking around this in order to provide
907        descriptive messages when something goes wrong, but this method is
908        essentially just:
909
910            return ExampleModel.objects.create(**validated_data)
911
912        If there are many to many fields present on the instance then they
913        cannot be set until the model is instantiated, in which case the
914        implementation is like so:
915
916            example_relationship = validated_data.pop('example_relationship')
917            instance = ExampleModel.objects.create(**validated_data)
918            instance.example_relationship = example_relationship
919            return instance
920
921        The default implementation also does not handle nested relationships.
922        If you want to support writable nested relationships you'll need
923        to write an explicit `.create()` method.
924        """
925        raise_errors_on_nested_writes('create', self, validated_data)
926
927        ModelClass = self.Meta.model
928
929        # Remove many-to-many relationships from validated_data.
930        # They are not valid arguments to the default `.create()` method,
931        # as they require that the instance has already been saved.
932        info = model_meta.get_field_info(ModelClass)
933        many_to_many = {}
934        for field_name, relation_info in info.relations.items():
935            if relation_info.to_many and (field_name in validated_data):
936                many_to_many[field_name] = validated_data.pop(field_name)
937
938        try:
939            instance = ModelClass._default_manager.create(**validated_data)
940        except TypeError:
941            tb = traceback.format_exc()
942            msg = (
943                'Got a `TypeError` when calling `%s.%s.create()`. '
944                'This may be because you have a writable field on the '
945                'serializer class that is not a valid argument to '
946                '`%s.%s.create()`. You may need to make the field '
947                'read-only, or override the %s.create() method to handle '
948                'this correctly.\nOriginal exception was:\n %s' %
949                (
950                    ModelClass.__name__,
951                    ModelClass._default_manager.name,
952                    ModelClass.__name__,
953                    ModelClass._default_manager.name,
954                    self.__class__.__name__,
955                    tb
956                )
957            )
958            raise TypeError(msg)
959
960        # Save many-to-many relationships after the instance is created.
961        if many_to_many:
962            for field_name, value in many_to_many.items():
963                field = getattr(instance, field_name)
964                field.set(value)
965
966        return instance
967
968    def update(self, instance, validated_data):
969        raise_errors_on_nested_writes('update', self, validated_data)
970        info = model_meta.get_field_info(instance)
971
972        # Simply set each attribute on the instance, and then save it.
973        # Note that unlike `.create()` we don't need to treat many-to-many
974        # relationships as being a special case. During updates we already
975        # have an instance pk for the relationships to be associated with.
976        m2m_fields = []
977        for attr, value in validated_data.items():
978            if attr in info.relations and info.relations[attr].to_many:
979                m2m_fields.append((attr, value))
980            else:
981                setattr(instance, attr, value)
982
983        instance.save()
984
985        # Note that many-to-many fields are set after updating instance.
986        # Setting m2m fields triggers signals which could potentially change
987        # updated instance and we do not want it to collide with .update()
988        for attr, value in m2m_fields:
989            field = getattr(instance, attr)
990            field.set(value)
991
992        return instance
993
994    # Determine the fields to apply...
995
996    def get_fields(self):
997        """
998        Return the dict of field names -> field instances that should be
999        used for `self.fields` when instantiating the serializer.
1000        """
1001        if self.url_field_name is None:
1002            self.url_field_name = api_settings.URL_FIELD_NAME
1003
1004        assert hasattr(self, 'Meta'), (
1005            'Class {serializer_class} missing "Meta" attribute'.format(
1006                serializer_class=self.__class__.__name__
1007            )
1008        )
1009        assert hasattr(self.Meta, 'model'), (
1010            'Class {serializer_class} missing "Meta.model" attribute'.format(
1011                serializer_class=self.__class__.__name__
1012            )
1013        )
1014        if model_meta.is_abstract_model(self.Meta.model):
1015            raise ValueError(
1016                'Cannot use ModelSerializer with Abstract Models.'
1017            )
1018
1019        declared_fields = copy.deepcopy(self._declared_fields)
1020        model = getattr(self.Meta, 'model')
1021        depth = getattr(self.Meta, 'depth', 0)
1022
1023        if depth is not None:
1024            assert depth >= 0, "'depth' may not be negative."
1025            assert depth <= 10, "'depth' may not be greater than 10."
1026
1027        # Retrieve metadata about fields & relationships on the model class.
1028        info = model_meta.get_field_info(model)
1029        field_names = self.get_field_names(declared_fields, info)
1030
1031        # Determine any extra field arguments and hidden fields that
1032        # should be included
1033        extra_kwargs = self.get_extra_kwargs()
1034        extra_kwargs, hidden_fields = self.get_uniqueness_extra_kwargs(
1035            field_names, declared_fields, extra_kwargs
1036        )
1037
1038        # Determine the fields that should be included on the serializer.
1039        fields = OrderedDict()
1040
1041        for field_name in field_names:
1042            # If the field is explicitly declared on the class then use that.
1043            if field_name in declared_fields:
1044                fields[field_name] = declared_fields[field_name]
1045                continue
1046
1047            extra_field_kwargs = extra_kwargs.get(field_name, {})
1048            source = extra_field_kwargs.get('source', '*')
1049            if source == '*':
1050                source = field_name
1051
1052            # Determine the serializer field class and keyword arguments.
1053            field_class, field_kwargs = self.build_field(
1054                source, info, model, depth
1055            )
1056
1057            # Include any kwargs defined in `Meta.extra_kwargs`
1058            field_kwargs = self.include_extra_kwargs(
1059                field_kwargs, extra_field_kwargs
1060            )
1061
1062            # Create the serializer field.
1063            fields[field_name] = field_class(**field_kwargs)
1064
1065        # Add in any hidden fields.
1066        fields.update(hidden_fields)
1067
1068        return fields
1069
1070    # Methods for determining the set of field names to include...
1071
1072    def get_field_names(self, declared_fields, info):
1073        """
1074        Returns the list of all field names that should be created when
1075        instantiating this serializer class. This is based on the default
1076        set of fields, but also takes into account the `Meta.fields` or
1077        `Meta.exclude` options if they have been specified.
1078        """
1079        fields = getattr(self.Meta, 'fields', None)
1080        exclude = getattr(self.Meta, 'exclude', None)
1081
1082        if fields and fields != ALL_FIELDS and not isinstance(fields, (list, tuple)):
1083            raise TypeError(
1084                'The `fields` option must be a list or tuple or "__all__". '
1085                'Got %s.' % type(fields).__name__
1086            )
1087
1088        if exclude and not isinstance(exclude, (list, tuple)):
1089            raise TypeError(
1090                'The `exclude` option must be a list or tuple. Got %s.' %
1091                type(exclude).__name__
1092            )
1093
1094        assert not (fields and exclude), (
1095            "Cannot set both 'fields' and 'exclude' options on "
1096            "serializer {serializer_class}.".format(
1097                serializer_class=self.__class__.__name__
1098            )
1099        )
1100
1101        assert not (fields is None and exclude is None), (
1102            "Creating a ModelSerializer without either the 'fields' attribute "
1103            "or the 'exclude' attribute has been deprecated since 3.3.0, "
1104            "and is now disallowed. Add an explicit fields = '__all__' to the "
1105            "{serializer_class} serializer.".format(
1106                serializer_class=self.__class__.__name__
1107            ),
1108        )
1109
1110        if fields == ALL_FIELDS:
1111            fields = None
1112
1113        if fields is not None:
1114            # Ensure that all declared fields have also been included in the
1115            # `Meta.fields` option.
1116
1117            # Do not require any fields that are declared in a parent class,
1118            # in order to allow serializer subclasses to only include
1119            # a subset of fields.
1120            required_field_names = set(declared_fields)
1121            for cls in self.__class__.__bases__:
1122                required_field_names -= set(getattr(cls, '_declared_fields', []))
1123
1124            for field_name in required_field_names:
1125                assert field_name in fields, (
1126                    "The field '{field_name}' was declared on serializer "
1127                    "{serializer_class}, but has not been included in the "
1128                    "'fields' option.".format(
1129                        field_name=field_name,
1130                        serializer_class=self.__class__.__name__
1131                    )
1132                )
1133            return fields
1134
1135        # Use the default set of field names if `Meta.fields` is not specified.
1136        fields = self.get_default_field_names(declared_fields, info)
1137
1138        if exclude is not None:
1139            # If `Meta.exclude` is included, then remove those fields.
1140            for field_name in exclude:
1141                assert field_name not in self._declared_fields, (
1142                    "Cannot both declare the field '{field_name}' and include "
1143                    "it in the {serializer_class} 'exclude' option. Remove the "
1144                    "field or, if inherited from a parent serializer, disable "
1145                    "with `{field_name} = None`."
1146                    .format(
1147                        field_name=field_name,
1148                        serializer_class=self.__class__.__name__
1149                    )
1150                )
1151
1152                assert field_name in fields, (
1153                    "The field '{field_name}' was included on serializer "
1154                    "{serializer_class} in the 'exclude' option, but does "
1155                    "not match any model field.".format(
1156                        field_name=field_name,
1157                        serializer_class=self.__class__.__name__
1158                    )
1159                )
1160                fields.remove(field_name)
1161
1162        return fields
1163
1164    def get_default_field_names(self, declared_fields, model_info):
1165        """
1166        Return the default list of field names that will be used if the
1167        `Meta.fields` option is not specified.
1168        """
1169        return (
1170            [model_info.pk.name] +
1171            list(declared_fields) +
1172            list(model_info.fields) +
1173            list(model_info.forward_relations)
1174        )
1175
1176    # Methods for constructing serializer fields...
1177
1178    def build_field(self, field_name, info, model_class, nested_depth):
1179        """
1180        Return a two tuple of (cls, kwargs) to build a serializer field with.
1181        """
1182        if field_name in info.fields_and_pk:
1183            model_field = info.fields_and_pk[field_name]
1184            return self.build_standard_field(field_name, model_field)
1185
1186        elif field_name in info.relations:
1187            relation_info = info.relations[field_name]
1188            if not nested_depth:
1189                return self.build_relational_field(field_name, relation_info)
1190            else:
1191                return self.build_nested_field(field_name, relation_info, nested_depth)
1192
1193        elif hasattr(model_class, field_name):
1194            return self.build_property_field(field_name, model_class)
1195
1196        elif field_name == self.url_field_name:
1197            return self.build_url_field(field_name, model_class)
1198
1199        return self.build_unknown_field(field_name, model_class)
1200
1201    def build_standard_field(self, field_name, model_field):
1202        """
1203        Create regular model fields.
1204        """
1205        field_mapping = ClassLookupDict(self.serializer_field_mapping)
1206
1207        field_class = field_mapping[model_field]
1208        field_kwargs = get_field_kwargs(field_name, model_field)
1209
1210        # Special case to handle when a OneToOneField is also the primary key
1211        if model_field.one_to_one and model_field.primary_key:
1212            field_class = self.serializer_related_field
1213            field_kwargs['queryset'] = model_field.related_model.objects
1214
1215        if 'choices' in field_kwargs:
1216            # Fields with choices get coerced into `ChoiceField`
1217            # instead of using their regular typed field.
1218            field_class = self.serializer_choice_field
1219            # Some model fields may introduce kwargs that would not be valid
1220            # for the choice field. We need to strip these out.
1221            # Eg. models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES)
1222            valid_kwargs = {
1223                'read_only', 'write_only',
1224                'required', 'default', 'initial', 'source',
1225                'label', 'help_text', 'style',
1226                'error_messages', 'validators', 'allow_null', 'allow_blank',
1227                'choices'
1228            }
1229            for key in list(field_kwargs):
1230                if key not in valid_kwargs:
1231                    field_kwargs.pop(key)
1232
1233        if not issubclass(field_class, ModelField):
1234            # `model_field` is only valid for the fallback case of
1235            # `ModelField`, which is used when no other typed field
1236            # matched to the model field.
1237            field_kwargs.pop('model_field', None)
1238
1239        if not issubclass(field_class, CharField) and not issubclass(field_class, ChoiceField):
1240            # `allow_blank` is only valid for textual fields.
1241            field_kwargs.pop('allow_blank', None)
1242
1243        is_django_jsonfield = hasattr(models, 'JSONField') and isinstance(model_field, models.JSONField)
1244        if (postgres_fields and isinstance(model_field, postgres_fields.JSONField)) or is_django_jsonfield:
1245            # Populate the `encoder` argument of `JSONField` instances generated
1246            # for the model `JSONField`.
1247            field_kwargs['encoder'] = getattr(model_field, 'encoder', None)
1248            if is_django_jsonfield:
1249                field_kwargs['decoder'] = getattr(model_field, 'decoder', None)
1250
1251        if postgres_fields and isinstance(model_field, postgres_fields.ArrayField):
1252            # Populate the `child` argument on `ListField` instances generated
1253            # for the PostgreSQL specific `ArrayField`.
1254            child_model_field = model_field.base_field
1255            child_field_class, child_field_kwargs = self.build_standard_field(
1256                'child', child_model_field
1257            )
1258            field_kwargs['child'] = child_field_class(**child_field_kwargs)
1259
1260        return field_class, field_kwargs
1261
1262    def build_relational_field(self, field_name, relation_info):
1263        """
1264        Create fields for forward and reverse relationships.
1265        """
1266        field_class = self.serializer_related_field
1267        field_kwargs = get_relation_kwargs(field_name, relation_info)
1268
1269        to_field = field_kwargs.pop('to_field', None)
1270        if to_field and not relation_info.reverse and not relation_info.related_model._meta.get_field(to_field).primary_key:
1271            field_kwargs['slug_field'] = to_field
1272            field_class = self.serializer_related_to_field
1273
1274        # `view_name` is only valid for hyperlinked relationships.
1275        if not issubclass(field_class, HyperlinkedRelatedField):
1276            field_kwargs.pop('view_name', None)
1277
1278        return field_class, field_kwargs
1279
1280    def build_nested_field(self, field_name, relation_info, nested_depth):
1281        """
1282        Create nested fields for forward and reverse relationships.
1283        """
1284        class NestedSerializer(ModelSerializer):
1285            class Meta:
1286                model = relation_info.related_model
1287                depth = nested_depth - 1
1288                fields = '__all__'
1289
1290        field_class = NestedSerializer
1291        field_kwargs = get_nested_relation_kwargs(relation_info)
1292
1293        return field_class, field_kwargs
1294
1295    def build_property_field(self, field_name, model_class):
1296        """
1297        Create a read only field for model methods and properties.
1298        """
1299        field_class = ReadOnlyField
1300        field_kwargs = {}
1301
1302        return field_class, field_kwargs
1303
1304    def build_url_field(self, field_name, model_class):
1305        """
1306        Create a field representing the object's own URL.
1307        """
1308        field_class = self.serializer_url_field
1309        field_kwargs = get_url_kwargs(model_class)
1310
1311        return field_class, field_kwargs
1312
1313    def build_unknown_field(self, field_name, model_class):
1314        """
1315        Raise an error on any unknown fields.
1316        """
1317        raise ImproperlyConfigured(
1318            'Field name `%s` is not valid for model `%s`.' %
1319            (field_name, model_class.__name__)
1320        )
1321
1322    def include_extra_kwargs(self, kwargs, extra_kwargs):
1323        """
1324        Include any 'extra_kwargs' that have been included for this field,
1325        possibly removing any incompatible existing keyword arguments.
1326        """
1327        if extra_kwargs.get('read_only', False):
1328            for attr in [
1329                'required', 'default', 'allow_blank', 'allow_null',
1330                'min_length', 'max_length', 'min_value', 'max_value',
1331                'validators', 'queryset'
1332            ]:
1333                kwargs.pop(attr, None)
1334
1335        if extra_kwargs.get('default') and kwargs.get('required') is False:
1336            kwargs.pop('required')
1337
1338        if extra_kwargs.get('read_only', kwargs.get('read_only', False)):
1339            extra_kwargs.pop('required', None)  # Read only fields should always omit the 'required' argument.
1340
1341        kwargs.update(extra_kwargs)
1342
1343        return kwargs
1344
1345    # Methods for determining additional keyword arguments to apply...
1346
1347    def get_extra_kwargs(self):
1348        """
1349        Return a dictionary mapping field names to a dictionary of
1350        additional keyword arguments.
1351        """
1352        extra_kwargs = copy.deepcopy(getattr(self.Meta, 'extra_kwargs', {}))
1353
1354        read_only_fields = getattr(self.Meta, 'read_only_fields', None)
1355        if read_only_fields is not None:
1356            if not isinstance(read_only_fields, (list, tuple)):
1357                raise TypeError(
1358                    'The `read_only_fields` option must be a list or tuple. '
1359                    'Got %s.' % type(read_only_fields).__name__
1360                )
1361            for field_name in read_only_fields:
1362                kwargs = extra_kwargs.get(field_name, {})
1363                kwargs['read_only'] = True
1364                extra_kwargs[field_name] = kwargs
1365
1366        else:
1367            # Guard against the possible misspelling `readonly_fields` (used
1368            # by the Django admin and others).
1369            assert not hasattr(self.Meta, 'readonly_fields'), (
1370                'Serializer `%s.%s` has field `readonly_fields`; '
1371                'the correct spelling for the option is `read_only_fields`.' %
1372                (self.__class__.__module__, self.__class__.__name__)
1373            )
1374
1375        return extra_kwargs
1376
1377    def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs):
1378        """
1379        Return any additional field options that need to be included as a
1380        result of uniqueness constraints on the model. This is returned as
1381        a two-tuple of:
1382
1383        ('dict of updated extra kwargs', 'mapping of hidden fields')
1384        """
1385        if getattr(self.Meta, 'validators', None) is not None:
1386            return (extra_kwargs, {})
1387
1388        model = getattr(self.Meta, 'model')
1389        model_fields = self._get_model_fields(
1390            field_names, declared_fields, extra_kwargs
1391        )
1392
1393        # Determine if we need any additional `HiddenField` or extra keyword
1394        # arguments to deal with `unique_for` dates that are required to
1395        # be in the input data in order to validate it.
1396        unique_constraint_names = set()
1397
1398        for model_field in model_fields.values():
1399            # Include each of the `unique_for_*` field names.
1400            unique_constraint_names |= {model_field.unique_for_date, model_field.unique_for_month,
1401                                        model_field.unique_for_year}
1402
1403        unique_constraint_names -= {None}
1404
1405        # Include each of the `unique_together` field names,
1406        # so long as all the field names are included on the serializer.
1407        for parent_class in [model] + list(model._meta.parents):
1408            for unique_together_list in parent_class._meta.unique_together:
1409                if set(field_names).issuperset(unique_together_list):
1410                    unique_constraint_names |= set(unique_together_list)
1411
1412        # Now we have all the field names that have uniqueness constraints
1413        # applied, we can add the extra 'required=...' or 'default=...'
1414        # arguments that are appropriate to these fields, or add a `HiddenField` for it.
1415        hidden_fields = {}
1416        uniqueness_extra_kwargs = {}
1417
1418        for unique_constraint_name in unique_constraint_names:
1419            # Get the model field that is referred too.
1420            unique_constraint_field = model._meta.get_field(unique_constraint_name)
1421
1422            if getattr(unique_constraint_field, 'auto_now_add', None):
1423                default = CreateOnlyDefault(timezone.now)
1424            elif getattr(unique_constraint_field, 'auto_now', None):
1425                default = timezone.now
1426            elif unique_constraint_field.has_default():
1427                default = unique_constraint_field.default
1428            else:
1429                default = empty
1430
1431            if unique_constraint_name in model_fields:
1432                # The corresponding field is present in the serializer
1433                if default is empty:
1434                    uniqueness_extra_kwargs[unique_constraint_name] = {'required': True}
1435                else:
1436                    uniqueness_extra_kwargs[unique_constraint_name] = {'default': default}
1437            elif default is not empty:
1438                # The corresponding field is not present in the
1439                # serializer. We have a default to use for it, so
1440                # add in a hidden field that populates it.
1441                hidden_fields[unique_constraint_name] = HiddenField(default=default)
1442
1443        # Update `extra_kwargs` with any new options.
1444        for key, value in uniqueness_extra_kwargs.items():
1445            if key in extra_kwargs:
1446                value.update(extra_kwargs[key])
1447            extra_kwargs[key] = value
1448
1449        return extra_kwargs, hidden_fields
1450
1451    def _get_model_fields(self, field_names, declared_fields, extra_kwargs):
1452        """
1453        Returns all the model fields that are being mapped to by fields
1454        on the serializer class.
1455        Returned as a dict of 'model field name' -> 'model field'.
1456        Used internally by `get_uniqueness_field_options`.
1457        """
1458        model = getattr(self.Meta, 'model')
1459        model_fields = {}
1460
1461        for field_name in field_names:
1462            if field_name in declared_fields:
1463                # If the field is declared on the serializer
1464                field = declared_fields[field_name]
1465                source = field.source or field_name
1466            else:
1467                try:
1468                    source = extra_kwargs[field_name]['source']
1469                except KeyError:
1470                    source = field_name
1471
1472            if '.' in source or source == '*':
1473                # Model fields will always have a simple source mapping,
1474                # they can't be nested attribute lookups.
1475                continue
1476
1477            try:
1478                field = model._meta.get_field(source)
1479                if isinstance(field, DjangoModelField):
1480                    model_fields[source] = field
1481            except FieldDoesNotExist:
1482                pass
1483
1484        return model_fields
1485
1486    # Determine the validators to apply...
1487
1488    def get_validators(self):
1489        """
1490        Determine the set of validators to use when instantiating serializer.
1491        """
1492        # If the validators have been declared explicitly then use that.
1493        validators = getattr(getattr(self, 'Meta', None), 'validators', None)
1494        if validators is not None:
1495            return list(validators)
1496
1497        # Otherwise use the default set of validators.
1498        return (
1499            self.get_unique_together_validators() +
1500            self.get_unique_for_date_validators()
1501        )
1502
1503    def get_unique_together_validators(self):
1504        """
1505        Determine a default set of validators for any unique_together constraints.
1506        """
1507        model_class_inheritance_tree = (
1508            [self.Meta.model] +
1509            list(self.Meta.model._meta.parents)
1510        )
1511
1512        # The field names we're passing though here only include fields
1513        # which may map onto a model field. Any dotted field name lookups
1514        # cannot map to a field, and must be a traversal, so we're not
1515        # including those.
1516        field_sources = OrderedDict(
1517            (field.field_name, field.source) for field in self._writable_fields
1518            if (field.source != '*') and ('.' not in field.source)
1519        )
1520
1521        # Special Case: Add read_only fields with defaults.
1522        field_sources.update(OrderedDict(
1523            (field.field_name, field.source) for field in self.fields.values()
1524            if (field.read_only) and (field.default != empty) and (field.source != '*') and ('.' not in field.source)
1525        ))
1526
1527        # Invert so we can find the serializer field names that correspond to
1528        # the model field names in the unique_together sets. This also allows
1529        # us to check that multiple fields don't map to the same source.
1530        source_map = defaultdict(list)
1531        for name, source in field_sources.items():
1532            source_map[source].append(name)
1533
1534        # Note that we make sure to check `unique_together` both on the
1535        # base model class, but also on any parent classes.
1536        validators = []
1537        for parent_class in model_class_inheritance_tree:
1538            for unique_together in parent_class._meta.unique_together:
1539                # Skip if serializer does not map to all unique together sources
1540                if not set(source_map).issuperset(unique_together):
1541                    continue
1542
1543                for source in unique_together:
1544                    assert len(source_map[source]) == 1, (
1545                        "Unable to create `UniqueTogetherValidator` for "
1546                        "`{model}.{field}` as `{serializer}` has multiple "
1547                        "fields ({fields}) that map to this model field. "
1548                        "Either remove the extra fields, or override "
1549                        "`Meta.validators` with a `UniqueTogetherValidator` "
1550                        "using the desired field names."
1551                        .format(
1552                            model=self.Meta.model.__name__,
1553                            serializer=self.__class__.__name__,
1554                            field=source,
1555                            fields=', '.join(source_map[source]),
1556                        )
1557                    )
1558
1559                field_names = tuple(source_map[f][0] for f in unique_together)
1560                validator = UniqueTogetherValidator(
1561                    queryset=parent_class._default_manager,
1562                    fields=field_names
1563                )
1564                validators.append(validator)
1565        return validators
1566
1567    def get_unique_for_date_validators(self):
1568        """
1569        Determine a default set of validators for the following constraints:
1570
1571        * unique_for_date
1572        * unique_for_month
1573        * unique_for_year
1574        """
1575        info = model_meta.get_field_info(self.Meta.model)
1576        default_manager = self.Meta.model._default_manager
1577        field_names = [field.source for field in self.fields.values()]
1578
1579        validators = []
1580
1581        for field_name, field in info.fields_and_pk.items():
1582            if field.unique_for_date and field_name in field_names:
1583                validator = UniqueForDateValidator(
1584                    queryset=default_manager,
1585                    field=field_name,
1586                    date_field=field.unique_for_date
1587                )
1588                validators.append(validator)
1589
1590            if field.unique_for_month and field_name in field_names:
1591                validator = UniqueForMonthValidator(
1592                    queryset=default_manager,
1593                    field=field_name,
1594                    date_field=field.unique_for_month
1595                )
1596                validators.append(validator)
1597
1598            if field.unique_for_year and field_name in field_names:
1599                validator = UniqueForYearValidator(
1600                    queryset=default_manager,
1601                    field=field_name,
1602                    date_field=field.unique_for_year
1603                )
1604                validators.append(validator)
1605
1606        return validators
1607
1608
1609class HyperlinkedModelSerializer(ModelSerializer):
1610    """
1611    A type of `ModelSerializer` that uses hyperlinked relationships instead
1612    of primary key relationships. Specifically:
1613
1614    * A 'url' field is included instead of the 'id' field.
1615    * Relationships to other instances are hyperlinks, instead of primary keys.
1616    """
1617    serializer_related_field = HyperlinkedRelatedField
1618
1619    def get_default_field_names(self, declared_fields, model_info):
1620        """
1621        Return the default list of field names that will be used if the
1622        `Meta.fields` option is not specified.
1623        """
1624        return (
1625            [self.url_field_name] +
1626            list(declared_fields) +
1627            list(model_info.fields) +
1628            list(model_info.forward_relations)
1629        )
1630
1631    def build_nested_field(self, field_name, relation_info, nested_depth):
1632        """
1633        Create nested fields for forward and reverse relationships.
1634        """
1635        class NestedSerializer(HyperlinkedModelSerializer):
1636            class Meta:
1637                model = relation_info.related_model
1638                depth = nested_depth - 1
1639                fields = '__all__'
1640
1641        field_class = NestedSerializer
1642        field_kwargs = get_nested_relation_kwargs(relation_info)
1643
1644        return field_class, field_kwargs
1645