diff --git a/docs/custom_spec.rst b/docs/custom_spec.rst index 1ab6b6d..328a9c1 100644 --- a/docs/custom_spec.rst +++ b/docs/custom_spec.rst @@ -212,7 +212,8 @@ Schema generation of ``serializers.SerializerMethodField`` is supported in two w Serializer ``Meta`` nested class ******************************** -You can define some per-serializer options by adding a ``Meta`` class to your serializer, e.g.: +You can define some per-serializer or per-field options by adding a ``Meta`` class to your ``Serializer`` or +serializer ``Field``, e.g.: .. code-block:: python @@ -236,6 +237,64 @@ The available options are: which are converted to Swagger ``Schema`` attribute names according to :func:`.make_swagger_name`. Attribute names and values must conform to the `OpenAPI 2.0 specification `_. +Suppose you wanted to model an email using a `JSONField` to store the subject and body for performance reasons: + +.. code-block:: python + + from django.contrib.postgres.fields import JSONField + + class Email(models.Model): + # Store data as JSON, but the data should be made up of + # an object that has two properties, "subject" and "body" + # Example: + # { + # "subject": "My Title", + # "body": "The body of the message.", + # } + message = JSONField() + +To instruct ``drf-yasg`` to output an OpenAPI schema that matches this, create a custom ``JSONField``: + +.. code-block:: python + + class EmailMessageField(serializers.JSONField): + class Meta: + swagger_schema_fields = { + "type": openapi.TYPE_OBJECT, + "title": "Email", + "properties": { + "subject": openapi.Schema( + title="Email subject", + type=openapi.TYPE_STRING, + ), + "body": openapi.Schema( + title="Email body", + type=openapi.TYPE_STRING, + ), + }, + "required": ["subject", "body"], + } + + class EmailSerializer(ModelSerializer): + class Meta: + model = Email + fields = "__all__" + + message = EmailMessageField() + +.. Warning:: + + Overriding a default ``Field`` generated by a ``ModelSerializer`` will also override automatically + generated validators for that ``Field``. To add ``Serializer`` validation back in manually, see the relevant + `DRF Validators`_ and `DRF Fields`_ documentation. + + One example way to do this is to set the ``default_validators`` attribute on a field. + + .. code-block:: python + + class EmailMessageField(serializers.JSONField): + default_validators = [my_custom_email_validator] + ... ************************* Subclassing and extending @@ -389,3 +448,5 @@ A second example, of a :class:`~.inspectors.FieldInspector` that removes the ``t .. _Python 3 type hinting: https://docs.python.org/3/library/typing.html +.. _DRF Validators: https://www.django-rest-framework.org/api-guide/validators/ +.. _DRF Fields: https://www.django-rest-framework.org/api-guide/fields/#validators