我需要创建一个抽象Django模型,并且我希望强制执行所有模型--继承者重新定义该字段。我试过了但有个例外:
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操作。
知道如何模仿抽象场吗?
发布于 2018-08-30 11:17:03
这不可能在定义类时实例化模型字段,因此使用此实现,您将永远无法只导入模型文件。
正确的解决方案是使用自定义元类--它必须继承django自己的模型元类。下面是Python2语法中的一个示例实现(您肯定需要对它进行改进),我让您检查文档中关于Python3的小语法差异。
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以外的任何东西都将被接受)。
发布于 2018-08-30 10:02:03
建议您使用OneToOne关系实现继承。
您想要做的可能是:https://docs.djangoproject.com/en/2.1/topics/db/models/#abstract-base-classes
https://stackoverflow.com/questions/52094214
复制相似问题