Django多重继承与不同的表

Posted

技术标签:

【中文标题】Django多重继承与不同的表【英文标题】:Django Multiple inheritance with different tables 【发布时间】:2017-10-14 18:36:06 【问题描述】:

我尝试创建一些模型。我实际上查看了一些示例,但大多数都不起作用。示例:

class Piece(models.Model):
    name =  models.CharField(max_length=100)    
    class Meta:
        abstract = True

class Article(Piece):
    pass        

class Book(Piece):
    pass

class Monday(Book, Article):
    pass    
class Tuesday(Book, Article):
    pass

所以我的目标是通过这样的方式获得价值 -> Monday.Article.name。 我希望每个工作日都有不同的表格,其中包含文章的名称。这是我得到的错误:

ERRORS:
Testing.Monday: (models.E005) The field 'id' from parent model 'Testing.book' ***es with the field 'id' from parent model 'Testing.article'.
Testing.Monday: (models.E005) The field 'name' from parent model 'Testing.book' ***es with the field 'name' from parent model 'Testing.article'.
Testing.Tuesday: (models.E005) The field 'id' from parent model 'Testing.book' ***es with the field 'id' from parent model 'Testing.article'.
Testing.Tuesday: (models.E005) The field 'name' from parent model 'Testing.book' ***es with the field 'name' from parent model 'Testing.article'.

看起来我的文章和书籍使用了相同的名称。这是如何工作的?

编辑:使用这个:

class Article(Piece):
   article_id = models.AutoField(primary_key=True)

class Book(Piece):
   book_id = models.AutoField(primary_key=True)

会导致这个错误:

Testing.Monday: (models.E005) The field 'piece_ptr' from parent model 
'Testing.book' ***es with the field 'piece_ptr' from parent model 
'Testing.article'.

唯一的解决方案是: article_to_piece = models.OneToOneField(Piece, parent_link=True)但这不会生成日期和书籍/文章之间的链接。我只能为这一天添加一个名字。

【问题讨论】:

这是一个非常糟糕的主意。只需使用带有“日”字段的单个表。 好吧,我想我必须按照你的方式去做!你能解释一下为什么我的方法不好吗?除了它不起作用 【参考方案1】:

问题是因为两个模型的主字段都是 id,并且一个表不能有 2 个基于相同名称的列,这样做可以解决您的错误

class Article(Piece):
    id = models.AutoField(primary_key=True)
    name= models.CharField(max_length=100)

class Book(Piece):
    book_id = models.AutoField(primary_key=True)
    book_name= models.CharField(max_length=100)

【讨论】:

这实际上不是我所希望的,但它可能对其他人有用!【参考方案2】:

您应该尝试在子类上调用 init,例如:

class Monday(Book, Article):
    id = models.AutoField(primary_key=True)
    name= models.CharField(max_length=100)

    def __init__(self, *args, **kwargs):
        return super().__init__(*args, **kwargs)


class OtherDay(Book, Article):
    book_id = models.AutoField(primary_key=True)
    book_name= models.CharField(max_length=100)

    def __init__(self, *args, **kwargs):
        return super().__init__(*args, **kwargs)

这是因为,作为 Python 类,super() 方法只会调用一次超类定义,而简单继承会为每个超类调用 ini()。

【讨论】:

以上是关于Django多重继承与不同的表的主要内容,如果未能解决你的问题,请参考以下文章

Django:从带有元的抽象类的多重继承

django中的Python多重继承函数覆盖和ListView

C++的多重继承

多重继承如何与 super() 和不同的 __init__() 参数一起工作?

Javascript中的多重继承与原型链

多继承 与 多重继承