首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >定义抽象django模型字段

定义抽象django模型字段
EN

Stack Overflow用户
提问于 2018-08-30 09:58:32
回答 2查看 505关注 0票数 1

我需要创建一个抽象Django模型,并且我希望强制执行所有模型--继承者重新定义该字段。我试过了但有个例外:

代码语言:javascript
复制
from django.db import models


class AbstractField(models.Field):
    description = "Abstract Field"

    def __init__(self):
        raise NotImplementedError("You have to redefine your field in model.")


class MyAbstractModel(models.Model):
    id = models.AutoField(primary_key=True)
    redefine_me_please = AbstractField()

    class Meta:
        abstract = True


class MyNotAbstractModel(MyAbstractModel):
    redefine_me_please = models.CharField(verbose_name='Name', max_length=255)

一个例外是NotImplementedError on makemigrations操作。

知道如何模仿抽象场吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-30 11:17:03

这不可能在定义类时实例化模型字段,因此使用此实现,您将永远无法只导入模型文件。

正确的解决方案是使用自定义元类--它必须继承django自己的模型元类。下面是Python2语法中的一个示例实现(您肯定需要对它进行改进),我让您检查文档中关于Python3的小语法差异。

代码语言:javascript
复制
from django.db.models.base import ModelBase

class MyAbstractField(object):
    pass

class MyAbstractModelType(ModelBase):
    def __new__(metacls, name, bases, attrs):
        must_check = True
        djmeta = attrs.get("Meta", None)
        if djmeta and getattr(djmeta, "abstract", False):
            must_check = False
        if must_check:          
            for attrname, value in attrs.items():
                if isinstance(value, MyAbstractField):
                    raise TypeError("Class %s must redefine %s" % (name, attrname))

        return ModelBase.__new__(metacls, name, bases, attrs)

class MyAbstractBase(models.Model):
    __metaclass__ = MyAbstractModelType

    foo = MyAbstractField()

    class Meta:
        abstract = True

class CorrectConcreteModel(MyAbstractBase):
    foo = models.IntegerField()

class IncorrectConcreteModel(MyAbstractBase):
    pass

使用此代码,一个不重新定义MyAbstractBase的具体foo子类(对于Django对“具体模型子类”的定义)将在导入时引发一个TypeError,这对编码器来说是显而易见的。一个可能的改进是检查foo是否是一个合适的模型字段( MyAbstractField以外的任何东西都将被接受)。

票数 2
EN

Stack Overflow用户

发布于 2018-08-30 10:02:03

建议您使用OneToOne关系实现继承。

您想要做的可能是:https://docs.djangoproject.com/en/2.1/topics/db/models/#abstract-base-classes

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52094214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档