1

I'm using djongo in order to connect my Django Rest Framework project to MongoDB,

As MongoDB using _id as its primary key, I changed my models like this:

from djongo import models

class MyModel(models.Model):
    _id = models.ObjectIdField(primary_key=True)
    name = models.CharField(max_length=200)

When I query data from database, the type of _id will be bson.objectid.ObjectId

So any time I want to query anything, I should do it like this:

from bson.objectid import ObjectId
from myapp.models import MyModel

MyModel.objects.get(pk=ObjectId('606e91bd371197379e9bf919'))
# or
MyModel.objects.filter(_id=ObjectId('606e91bd371197379e9bf919'))

and if I use MyModel.objects.filter(pk='606e91bd371197379e9bf919') it can't find the data in database

This additional ObjectId which is required for any query makes many problems because none of the pre-existing classes (like Forms, Views, Django Rest Framework Serializers, ....) act like that, so I should override all of them, and this cause many code duplications,

Is there a way to override any of Q/QuerySet/Model/Model Meta Class or a wrapper or anything else to apply the additional ObjectId for querying pk/id/_id field and solve this problem?

Is a better way to do this?

M.A. Heshmat Khah
  • 740
  • 12
  • 27

1 Answers1

-1

I would override the default manager get and filter methods to check if pk and/or _id are passed as kwargs and cast the value to ObjectId.

Here is an example overriding the get method and changing the pk value to an ObjectId.

class CustomManager(models.Manager):
    def get(self, **kwargs):
        pk = kwargs.get('pk')
        if pk:
            kwargs['pk'] = ObjectId(pk)
        return super().get(**kwargs)

class MyModel(models.Model):
    _id = models.ObjectIdField(primary_key=True)
    name = models.CharField(max_length=200)
    
    objects = CustomManager()
Marcel Canu
  • 27
  • 1
  • 3