如何让我的模型遵循DRY原则

时间:2016-11-04 19:36:10

标签: python django python-3.x django-models django-rest-framework

我有一个模型,我需要为劳动力应用程序代表不同的工作,例如:

from django.db import models

class PostFirstJobAd(models.Model):
    fist_job_ad_title = models.CharField(max_length=225)
    first_job_ad_description = models.TextField()
    created_at = models.DateTimeField(auto_now=True)

class PostSecondJobAd(models.Model):
    second_job_ad_title = models.CharField(max_length=225)
    second_job_ad_description = models.TextField()
    created_at = models.DateTimeField(auto_now=True)

class PostThirdJobAd(models.Model):
    third_job_ad_title = models.CharField(max_length=225)
    third_job_ad_description = models.TextField()
    created_at = models.DateTimeField(auto_now=True)

立即你可以看到我正在重复titledescriptioncreated_at,我只是更改字段的名称,它不是DRY而且代码开始闻到。原因是因为我想在django admin内单独注册每个作业,所以我在网站管理中会有明确的情况。

让他们干的一种方法是使用Abstract base classes,但我遇到了问题,因为来自文档:

  

此模型不会用于创建任何数据库表。   相反,当它被用作其他模型的基类时,它的字段   将被添加到儿童班的那些。

在这种情况下,什么是正确的方法,有人可以帮助我理解这一点。

2 个答案:

答案 0 :(得分:2)

使用抽象基础模型:

class JobAd(models.Model):
    title = models.CharField(max_length=225)
    description = models.TextField()
    created_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

class PostFirstJobAd(JobAd):
    pass

class PostSecondJobAd(JobAd):
    pass

class PostThirdJobAd(JobAd):
    pass

这将创建3个表。基类JobAd在db中没有表。

由于您似乎有3个不同的模型具有完全相同的代码,因此您应该质疑是否真的需要3个不同的模型。另一个选择是将它们全部存储在一个表中,并为"其他"添加另一个字段。事情。

class JobAd(models.Model):
    pos = models.CharField(max_length=100, choices=['first', 'second', 'third'])
    title = models.CharField(max_length=225)
    description = models.TextField()
    created_at = models.DateTimeField(auto_now=True)

pos的整数字段也是可能的。

答案 1 :(得分:1)

首先,抽象模型可能就是你需要的。根据业务需求,您可能需要在架构上稍微考虑一下。

事实上,如果你确实需要使用抽象基类:

class BaseJob(models.Model):
    title = models.CharField(max_length=255)
    # etc...

    class Meta:
        abstract = True

    def method_1(self):
        # base methods that work for instance data

一旦定义了,就可以在具体模型中实现基类。具体模型是不使用abstract = True元类属性(或代理等)的模型,如下所示:

class Job(BaseJob):
    pass

如果您需要其他字段,可以像任何其他模型字段一样定义它们,但是当您运行makemigrations时,您会发现在生成的迁移中会添加字段。