diff --git a/rest_framework/compat.py b/rest_framework/compat.py index ff21bacff..4cd7bac3d 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -16,6 +16,13 @@ def unicode_http_header(value): return value +# django-mongodb-backend +try: + from bson import ObjectId +except ImportError: + ObjectId = None + + # django.contrib.postgres requires psycopg2 try: from django.contrib.postgres import fields as postgres_fields diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 6989edc0a..b95f8fe1f 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -35,6 +35,11 @@ try: except ImportError: pytz = None +try: + from bson import ObjectId +except ImportError: + ObjectId = None + from rest_framework import ISO_8601 from rest_framework.compat import ip_address_validators from rest_framework.exceptions import ErrorDetail, ValidationError @@ -1745,6 +1750,15 @@ class HStoreField(DictField): ) +class ObjectIdRestField(Field): + def to_internal_value(self, data): + if not ObjectId.is_valid(data): + raise ValidationError('Invalid ObjectId') + + def to_representation(self, value): + return str(value) + + class JSONField(Field): default_error_messages = { 'invalid': _('Value must be valid JSON.') diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 0b87aa8fc..89a60b38a 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -27,7 +27,7 @@ from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ from rest_framework.compat import ( - get_referenced_base_fields_from_q, postgres_fields + get_referenced_base_fields_from_q, postgres_fields, ObjectId ) from rest_framework.exceptions import ErrorDetail, ValidationError from rest_framework.fields import get_error_detail @@ -938,6 +938,9 @@ class ModelSerializer(Serializer): serializer_field_mapping[postgres_fields.HStoreField] = HStoreField serializer_field_mapping[postgres_fields.ArrayField] = ListField serializer_field_mapping[postgres_fields.JSONField] = JSONField + if ObjectId: + from .fields import ObjectIdRestField + serializer_field_mapping[models.AutoField] = ObjectIdRestField serializer_related_field = PrimaryKeyRelatedField serializer_related_to_field = SlugRelatedField serializer_url_field = HyperlinkedIdentityField