1

I set up a Django REST Framework (DRF) in combination with djongo, since I'm having a legacy database in MongoDB/Mongo express. Everything runs through a docker container, but I don't think that this is the issue. My model looks like this:

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'

Next, my serializer is as follows:

from rest_framework import serializers
from .models import Event


class EventSerializer(serializers.ModelSerializer):

    class Meta:
        model = Event
        fields= "__all__"

And the view looks like this:

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)

As soon as I'm trying to post with

import requests

endpoint = "http://localhost:8080/event/"

get_response = requests.post(endpoint, {"date":"2022-06-01", "name":"Max Musterfrau", "locality":"North America"} )

I'm getting back the error message

TypeError: int() argument must be a string, a bytes-like object or a real number, not 'ObjectId'

Following the documentation and other StackOverflow questions, in my model ID = models.AutoField(primary_key=True) should create the index ID as the primary key and auto-increments it. But at the same time, MongoDB creates its own _id and the actual ID from my legacy database doesn't auto-increment. I've tried both suggested solutions from here, but unfortunately it didn't change a thing. Therefore, my question is: How can I auto-increment the ID from my legacy database when POSTing an object? How do I create it automatically?

Viktoria
  • 533
  • 2
  • 7
  • 24

1 Answers1

0

We need to create Separate serializer filed for _id = ObjectIdField like below

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__'
abhishek Singh
  • 332
  • 2
  • 7