DRF + Djongo: Как получить доступ и работать с ID из унаследованной базы данных?
Я установил Django REST Framework (DRF) в сочетании с djongo, так как у меня есть унаследованная база данных в MongoDB/Mongo express. Все работает через контейнер docker, но я не думаю, что проблема в этом. Моя модель выглядит следующим образом:
from django.db import models
## Event
class Event(models.Model):
ID = models.AutoField(primary_key=True)
date = models.DateField(default=None)
name = models.CharField(default=None, max_length=500)
locality = models.CharField(default=None, max_length=500)
class Meta:
ordering = ['ID']
db_table = 'event'
Далее, мой сериализатор выглядит следующим образом:
from rest_framework import serializers
from .models import Event
class EventSerializer(serializers.ModelSerializer):
class Meta:
model = Event
fields= "__all__"
И вид выглядит следующим образом:
from rest_framework import generics, status
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .serializers import *
from .models import *
## Events
@api_view(['GET', 'POST'])
def event_list(request):
if request.method == 'GET':
events = Event.objects.all().order_by('ID')
event_serializer = EventSerializer(events, many=True)
return Response(event_serializer.data)
elif request.method == 'POST':
event_serializer = EventSerializer(data=request.data)
if event_serializer.is_valid():
event_serializer.save()
return Response(event_serializer.data, status=status.HTTP_201_CREATED)
return Response(event_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Как только я пытаюсь отправить сообщение с
import requests
endpoint = "http://localhost:8080/event/"
get_response = requests.post(endpoint, {"date":"2022-06-01", "name":"Max Musterfrau", "locality":"North America"} )
Я получаю сообщение об ошибке
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'ObjectId'
Согласно документации и другим вопросам на StackOverflow, в моей модели ID = models.AutoField(primary_key=True)
должен создаваться индекс ID
как первичный ключ и автоинкремент. Но в то же время MongoDB создает свой собственный _id
и фактический ID
из моей старой базы данных не автоинкрементируется. Я пробовал оба предложенных решения из здесь, но, к сожалению, это ничего не изменило. Поэтому мой вопрос: Как я могу автоинкрементировать ID из моей старой базы данных при POST
создании объекта? Как мне создать его автоматически?
Нам нужно создать отдельный файл сериализатора для _id = ObjectIdField, как показано ниже
from bson import ObjectID
from bson.errors import InvalidID
class ObjectIdField(serializers.Field):
""" Serializer field for Djongo ObjectID fields """
def to_internal_value(self, data):
# Serialized value -> Database value
try:
return ObjectId(str(data)) # Get the ID, then build an ObjectID instance using it
except InvalidId:
raise serializers.ValidationError(
'`{}` is not a valid ObjectID'.format(data)
def to_representation(self, value):
# Database value -> Serialized value
if not ObjectId.is_valid(value): # User submitted ID's might not be properly structured
raise InvalidId
return smart_text(value)
class EventSerializer(ModelSerializer):
_id = ObjectIdField(read_only=True)
class Meta:
model = Event
fields = '__all__'