Python万里长征5(非教程)【mongo document model 加入到django admin管理后台研究】

这里写自定义目录标题

一、背景

在swagger接口文档中发现删除操作不如django admin管理后台来的方便,不用自己去手动输入id。
但是发现一个AttributeError报错,也就是unique_together 问题。

在这里插入图片描述
图1

图2
图2

如上图报错,是个keyerror问题。

看来mongoengine 虽说是orm库,但是并没有很好的对接支持django admin后台管理功能,不能像mysql model 一样可以加入后台方便管理。

二、解决方案

猜测在django 中unique_together是model 下class Meta的属性,但是在Document模型下添加属性并没有解决问题,于是找到/opt/work/venv_py39/lib/python3.9/site-packages/django/contrib/admin/views/main.py 的代码,做了下类型打印发现,有两个options的属性是相差很大的,显然unique_together也在这两个options模块下。

在这里插入图片描述
根据报错和源码研究,需要对options增加初始属性,但是我们这里只使用了Document,所以需要了解
doc和options的关系,


from django_mongoengine.forms.document_options import DocumentMetaWrapper
from django_mongoengine.document import DjangoFlavor
from django_mongoengine.fields import ObjectIdField
from mongoengine.base import metaclasses as mtc
from mongoengine import document as me
from functools import partial
from django.utils.functional import cached_property
from django.db.models import UniqueConstraint
mtc.ObjectIdField = partial(
    ObjectIdField, editable=False, auto_created=True, blank=True)


class DocMet(DocumentMetaWrapper):
    unique_together = []
    constraints = []

    @cached_property
    def total_unique_constraints(self):
        """
        Return a list of total unique constraints. Useful for determining set
        of fields guaranteed to be unique for all rows.
        """
        return [
            constraint
            for constraint in self.constraints
            if (
                isinstance(constraint, UniqueConstraint)
                and constraint.condition is None
                and not constraint.contains_expressions
            )
        ]


def django_meta(meta, *top_bases):
    class metaclass(meta):
        def __new__(cls, name, bases, attrs):
            change_bases = len(bases) == 1 and (
                bases[0].__name__ == "temporary_meta")
            if change_bases:
                new_bases = top_bases
            else:
                new_bases = ()
                for b in bases:
                    if getattr(b, 'swap_base', False):
                        new_bases += top_bases
                    else:
                        new_bases += (b,)
            new_cls = meta.__new__(cls, name, new_bases, attrs)
            new_cls._meta = DocMet(new_cls)
            return new_cls

    return type.__new__(metaclass, 'temporary_meta', (), {})


class Doc(
    django_meta(
        mtc.TopLevelDocumentMetaclass,
        DjangoFlavor,
        me.Document,
    )
):
    swap_base = True


重写了Document,这里简写了类名,避免冲突,也为了简单。

在这里插入图片描述

admin.site.register([CweDoc])

然后在admin.py中配置上述程序,既可以看到
在这里插入图片描述

改写还有TypeError: ‘metaclass’ object is not iterable 问题,遗留问题属于admin.ModelAdmin 继承使用问题了,也就是要增加展示字段,需要解决剩下的问题了,这里就先不记录了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值