Django如何设计模型的多个变种

时间:2016-07-21 03:44:31

标签: django inheritance django-models

说您是发布商并且有多种类型的文章。

标准文章,赞助文章和评论

赞助文章有一些赞助领域,赞助商和promotion_end_date

评论还有其他一些仅限审核的字段,例如产品返回地址

你会如何设计?

我曾经遇到过这个问题几次,而且我总是在一个模型中完成它,所有字段都可用但不是必需的。 但它只是感觉很糟糕,因为它为管理员留下了出错的空间。如果他们填写产品退货地址但不是评论怎么办?等

大多数时候你想在一个模型中,一起查询非常相似的对象,因为90%的fieldset在它们之间是相同的。对于寻找最受欢迎的

等内容非常有帮助

编辑:

这些模型几乎总是一起查询。因此将它们放在不同的表中然后解决它是没有意义的。 它们应该在同一个表中并编入索引。 否则,每个请求都会执行3次查询,而不是一次。然后必须在计算之后对查询进行合并和排序。

2 个答案:

答案 0 :(得分:2)

使用abstract base classes

class ArticleBase(models.Model):
    # fields

    class Meta:
        abstract = True

class Article(ArticleBase):
    pass

class SponsoredArticle(ArticleBase):
    # additional fields

class Review(ArticleBase):
    # additional fields

multi-table inheritance

class Article(models.Model):
    # fields

class SponsoredArticle(Article):
    # additional fields

class Review(Article):
    # additional fields

在后一种情况下,您可以使用articles查询所有Article.objects.select_related('sponsoredarticle', 'review').all()(您可以创建自定义管理器,以避免每次都输入select_related(...))。访问子类时,select_related()是避免数据库查询的必要条件,例如: G。 aricle.review

答案 1 :(得分:2)

您始终可以拥有一个可以由您命名的其他后续模型继承的基本模型。在你的情况下。

class BaseArticle(models.Model):
    class Meta:
        abstract = True
    fields that are common to the models that will be inheriting this


class StandardArticle(BaseArticle):
    fields specific to StandardArticle

您可以使用与StandardArticle

相同的方式使用其他模型