【问题标题】:Django override QuerySet for pkDjango 为 pk 覆盖 QuerySet
【发布时间】:2021-07-04 10:14:37
【问题描述】:

我正在使用djongo 将我的 Django Rest Framework 项目连接到 MongoDB,

由于 MongoDB 使用 _id 作为其主键,我将模型更改如下:

from djongo import models

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

当我从数据库中查询数据时,_id 的类型将是bson.objectid.ObjectId

所以任何时候我想查询任何东西,我都应该这样做:

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

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

如果我使用MyModel.objects.filter(pk='606e91bd371197379e9bf919'),它将无法在数据库中找到数据

任何查询都需要这个额外的ObjectId,这会产生很多问题,因为没有一个预先存在的类(如表单、视图、Django Rest Framework 序列化器......)像这样,所以我应该覆盖所有其中,这会导致许多代码重复,

有没有办法覆盖任何Q/QuerySet/Model/Model Meta Class 或包装器或其他任何东西来应用额外的ObjectId 来查询pk/id/@ 987654336@字段并解决这个问题?

有更好的方法吗?

【问题讨论】:

    标签: django mongodb django-rest-framework django-orm djongo


    【解决方案1】:

    我会覆盖默认管理器 get 和 filter 方法来检查 pk 和/或 _id 是否作为 kwargs 传递并将值转换为 ObjectId。

    这是一个覆盖 get 方法并将 pk 值更改为 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()
    

    【讨论】:

    • 这样,我应该覆盖管理器中的每个方法,filter,get,exclude,...
    • 另外,这样我就无法过滤与fieldname__id 或类似的关系。
    猜你喜欢
    • 1970-01-01
    • 2018-11-14
    • 2022-11-10
    • 2018-01-21
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 2014-06-15
    • 2021-06-18
    相关资源
    最近更新 更多