【问题标题】:How can I use supertype in django database model?如何在 django 数据库模型中使用超类型?
【发布时间】:2016-04-04 17:33:30
【问题描述】:

我的数据库中有下一个模型。 Question 代表一个问题和一个与之关联的投票,TextPollQuestion 在问题之前有一个文本,Answer 包含一个答案文本和问题的链接,UserAnswers 包含用户的答案:

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    poll = models.ForeignKey(Poll, null=True, blank=True)
    user_answers = models.ManyToManyField(UserProfile, through='UserAnswers')

class TextPollQuestion(Question):
    text = models.CharField(max_length=450)

class Answer(models.Model):
    answer_text = models.CharField(max_length=100)
    question = models.ForeignKey(Question, null=True, blank=True)

class UserAnswers(models.Model):
    question = models.ForeignKey(Question)
    user = models.ForeignKey(UserProfile)
    answer = models.CharField(max_length=40)

使用此代码,我必须创建AnswerUserAnswers 的另一个子类型以及连接到Question 模型的其他一些模型,以便将它们与TextPollQuestion 模型一起使用,但这显然违反了 DRY 原则。我应该使用什么来将所有模型链接到 QuestionTextPollQuestion 的某些超类型并避免重复模型?

【问题讨论】:

  • 我不认为它违反了 DRY 原则。你的问题和答案千差万别,没有太多抽象。
  • 在定义模型时需要小心:请记住,创建模型类不仅会创建类,还会创建额外的数据库表。您的模型在设计时应该考虑到数据库模式,而不是考虑 DRY 原则。如有必要,您可以使用抽象模型使其更加干燥。

标签: django database django-models django-orm


【解决方案1】:

关于你的问题的标题...

Django 在编写模型时有 3 个主要的“模式”用于子类化。

  1. Abstract model。抽象模型的主要用途是为您节省一些编码时间。比如说,您在几个相同的模型中有一些字段。您定义一个模型类来定义此字段并使其抽象。然后你定义其他模型类,它们应该包含这个字段并使它们成为你抽象模型的子类。这样抽象模型本身就不会得到一个单独的数据库表,但是每个子类(除非它是抽象的)都会得到它自己的表,其中包含在抽象模型中定义的字段。点击链接了解更多详情。
  2. Common model inheritance (Multi-table inheritance)。这通常在一个模型扩展另一个模型中表示的数据时使用。比如说,您有一个定义基本数据的模型,并且需要有更多细节的模型,这些细节很少使用。 IE。使用字段“用户名”、“密码”为“用户”建模,并为每个用户使用字段“年龄”、“性别”建模“个人资料”。然后你可以定义“用户”模型并将“配置文件”定义为它的子类。这将导致创建 2 个单独的表 - “用户”和“配置文件”,并通过 Django ORM 隐式地通过一对一关系链接。这几乎与您自己定义两个单独的模型而无需继承并添加连接它们的“OneToOne”字段一样。
  3. Proxy model。当您需要在现有模型上具有与已为其定义的行为不同的某些特殊行为时,通常使用此方法。这样你就有了一些原始模型,然后再定义一个模型,使其成为原始模型的子类,并声称它是“代理”。然后你可以重新定义这个子类的任何行为。这将导致在数据库中只为原始模型创建一个表,而要访问此表,您将能够使用这两个模型。

请记住,您定义的每个模型,除非它是“抽象”、“非托管”或“代理”,都会导致 Django ORM 在 DB 中为其创建一个表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2016-02-20
    • 2012-10-28
    • 2014-05-05
    相关资源
    最近更新 更多