===================== Django REST Framework ===================== .. versionadded:: 0.3.0 The classes in ``django_mongodb_extensions.rest_framework`` provide `Django REST Framework `_ (DRF) serializer support for :doc:`Django MongoDB Backend ` models. All models using :class:`~django_mongodb_backend.fields.ObjectIdAutoField` (the default primary key for MongoDB models) need :class:`~django_mongodb_extensions.rest_framework.MongoModelSerializer` rather than DRF's ``ModelSerializer``, because the ``ObjectId`` primary key requires special handling. Installation ============ This package requires Django REST Framework 3.16 or later. If you don't already have a compatible version of DRF installed, use the ``rest_framework`` extra to install it alongside this package: .. code-block:: console $ pip install "django-mongodb-extensions[rest_framework]" Then configure Django REST Framework by following its `installation instructions `_. Usage ===== ``MongoModelSerializer`` ------------------------ Use :class:`~django_mongodb_extensions.rest_framework.MongoModelSerializer` for regular Django models that contain MongoDB-specific fields:: from django_mongodb_extensions.rest_framework import MongoModelSerializer class BookSerializer(MongoModelSerializer): class Meta: model = Book fields = "__all__" ``MongoModelSerializer`` extends DRF's ``ModelSerializer`` and automatically generates the correct DRF fields for Django MongoDB Backend's fields: * :class:`~django_mongodb_backend.fields.ArrayField` * :class:`~django_mongodb_backend.fields.EmbeddedModelField` * :class:`~django_mongodb_backend.fields.EmbeddedModelArrayField` * :class:`~django_mongodb_backend.fields.PolymorphicEmbeddedModelField` (read-only) * :class:`~django_mongodb_backend.fields.PolymorphicEmbeddedModelArrayField` (read-only) * :class:`~django_mongodb_backend.fields.ObjectIdField` * :class:`~django_mongodb_backend.fields.ObjectIdAutoField` ``EmbeddedModelSerializer`` --------------------------- Use :class:`~django_mongodb_extensions.rest_framework.EmbeddedModelSerializer` for each :class:`~django_mongodb_backend.models.EmbeddedModel` you want to serialize. Set ``Meta.model`` and ``Meta.fields`` just like other `DRF serializers `_:: from django_mongodb_extensions.rest_framework import EmbeddedModelSerializer class AddressSerializer(EmbeddedModelSerializer): class Meta: model = Address fields = "__all__" Fields are auto-generated from the embedded model's field definitions, supporting the same MongoDB-specific field types as :class:`~django_mongodb_extensions.rest_framework.MongoModelSerializer`. Unless specified in ``Meta.fields`` the primary key field is excluded. ``to_internal_value()`` returns a model instance rather than a ``dict`` so that the result integrates with the Django MongoDB Backend ORM layer. Saving is not supported directly on ``EmbeddedModelSerializer`` — embedded models must be saved through their parent model. ``EmbeddedModelSerializer`` extends :class:`~django_mongodb_extensions.rest_framework.MongoModelSerializer` and supports the standard ``Meta`` options: ``fields``, ``exclude``, ``extra_kwargs``, and ``read_only_fields``. Examples ======== Single embedded model field ---------------------------- In ``models.py``:: from django.db import models from django_mongodb_backend.fields import EmbeddedModelField from django_mongodb_backend.models import EmbeddedModel class Address(EmbeddedModel): city = models.CharField(max_length=100) zip_code = models.CharField(max_length=20) class Person(models.Model): name = models.CharField(max_length=100) address = EmbeddedModelField(Address) In ``serializers.py``:: from django_mongodb_extensions.rest_framework import MongoModelSerializer from .models import Person class PersonSerializer(MongoModelSerializer): class Meta: model = Person fields = "__all__" The ``address`` field is auto-generated as a nested :class:`~django_mongodb_extensions.rest_framework.EmbeddedModelSerializer` for ``Address``. Serializing a ``Person`` instance:: >>> person = Person.objects.get(name="Alice") >>> data = PersonSerializer(person).data {"id": "...", "name": "Alice", "address": {"city": "Berlin", "zip_code": "10115"}} Deserializing and saving:: serializer = PersonSerializer(data=request.data) if serializer.is_valid(): serializer.save() To customize the embedded model's serialization, declare an :class:`~django_mongodb_extensions.rest_framework.EmbeddedModelSerializer` subclass and assign it as an explicit field:: from django_mongodb_extensions.rest_framework import ( EmbeddedModelSerializer, MongoModelSerializer, ) from .models import Address, Person class AddressSerializer(EmbeddedModelSerializer): class Meta: model = Address fields = "__all__" class PersonSerializer(MongoModelSerializer): address = AddressSerializer() class Meta: model = Person fields = "__all__" Array of embedded models ------------------------ In ``models.py``:: from django.db import models from django_mongodb_backend.fields import EmbeddedModelArrayField from django_mongodb_backend.models import EmbeddedModel class Tag(EmbeddedModel): label = models.CharField(max_length=50) class Article(models.Model): title = models.CharField(max_length=200) tags = EmbeddedModelArrayField(Tag, null=True) In ``serializers.py``:: from django_mongodb_extensions.rest_framework import MongoModelSerializer from .models import Article class ArticleSerializer(MongoModelSerializer): class Meta: model = Article fields = "__all__" The ``tags`` field is auto-generated and represented as a JSON array of objects: .. code-block:: json { "id": "...", "title": "Hello", "tags": [{"label": "python"}, {"label": "mongodb"}] } Polymorphic embedded model fields ---------------------------------- :class:`~django_mongodb_backend.fields.PolymorphicEmbeddedModelField` and :class:`~django_mongodb_backend.fields.PolymorphicEmbeddedModelArrayField` are serialized automatically by :class:`~django_mongodb_extensions.rest_framework.PolymorphicEmbeddedModelSerializer`, which dispatches to the correct concrete :class:`~django_mongodb_extensions.rest_framework.EmbeddedModelSerializer` based on the type of each instance: In ``models.py``:: from django.db import models from django_mongodb_backend.fields import PolymorphicEmbeddedModelField from django_mongodb_backend.models import EmbeddedModel class Dog(EmbeddedModel): name = models.CharField(max_length=100) barks = models.BooleanField(default=True) class Cat(EmbeddedModel): name = models.CharField(max_length=100) purrs = models.BooleanField(default=True) class PetOwner(models.Model): name = models.CharField(max_length=100) pet = PolymorphicEmbeddedModelField([Dog, Cat], null=True) In ``serializers.py``:: from django_mongodb_extensions.rest_framework import MongoModelSerializer from .models import PetOwner class PetOwnerSerializer(MongoModelSerializer): class Meta: model = PetOwner fields = "__all__" Serializing a ``PetOwner`` with a ``Dog`` instance:: >>> owner = PetOwner.objects.get(name="Alice") >>> data = PetOwnerSerializer(owner).data {"id": "...", "name": "Alice", "pet": {"_label": "myapp.Dog", "name": "Rex", "barks": true}} The ``pet`` field is read-only. Write operations are not supported for polymorphic embedded model fields.