Skip to main content
 首页 » 编程设计

python之Django中结合抽象模型类和多表继承

2024年11月01日40exmyth

我有三个模型类:

django.contrib.auth.models.User,引用为 User

mysite.models.Profile,简称为Profile

mysite.models.Subscriber,简称为Subscriber

Profile 以 well described 的方式继承自 User在文档中作为将自定义属性添加到 User 模型而不用担心可交换模型(仅在版本 1.5 中添加)的解决方案。

虽然 Profile 和 Subscriber 是不同的对象,但它们确实共享一些属性。也就是说,我想对两者都使用自定义主键算法,并以类似的方式覆盖 save() 方法,以便可以根据 DRY 重用代码。现在,如果两者都是普通模型类,那就很简单了:

class BaseProfile(models.Model): 
    key = models.PositiveIntegerField(primary_key=True) 
    activated = models.BooleanField(default=False) 
    ... 
 
    class Meta: 
        abstract = True 
 
    def save(): 
        ... 
 
class Profile(BaseProfile): 
   ... 
 
class Subscriber(BaseProfile): 
   ... 

但是,Profile已经使用了多表继承。我正在考虑类似这样的方法:

class BaseProfile(models.Model): 
    key = models.PositiveIntegerField(primary_key=True) 
    activated = models.BooleanField(default=False) 
    ... 
 
    class Meta: 
        abstract = True 
 
    def save(): 
        ... 
 
class Profile(BaseProfile, User): 
    user = models.OneToOneField(User, parent_link=True, blank=True, null=True, on_delete=models.CASCADE) 
    ... 
 
class Subscriber(BaseProfile): 
   ... 

这可能吗?如果是这样,我的情况需要什么继承顺序,以便以正确的方式调用模型字段和 save() 方法?两个模型类的 Meta 不会发生冲突吗?

请您参考如下方法:

您链接到的文档没有描述通过多表继承从 User 继承。它确实解释了您可以使用 OneToOneField 链接类似“配置文件”的对象。尝试:

class Profile(BaseProfile): 
    user = models.OneToOneField(User, blank=True, null=True, on_delete=models.CASCADE) 
    ... 

不过,我怀疑您实际上并不想要其中的 blank=True 和 null=True。

这种方法确实意味着您的 User 对象很可能没有与其对应的 Profile 对象相同的主键,但这对您来说可能没问题。