ManyToMany关系和中级模特(新手指导)

时间:2012-06-03 22:05:01

标签: django django-models dry

我非常感谢有关如何构建以下模型的一些指导。我想确保我以理想的方式做到这一点。

我想在工作中跟踪员工的一些信息。基本上,过去的教育和过去的工作经历

所以这里是我能想到的关系

  • 教育
    • 一名员工可以去过几所学校,每所学校可以有很多学生(m2m)
    • 学生在学校上学一段时间
    • 学生可以在同一所学校拥有多个学位,该学校提供多个学位(m2m)
  • 工作(与教育几乎相同)
    • m2m与员工和公司的关系
    • 员工在公司工作到一段时间
    • 雇员可以在一家公司(m2m)有几份工作

基本上遵循以上内容,这里是我编写的代码:

#make a list of numbers in a tuple
START_DATE_CHOICES = dict((str(x),str(x)) for x in range(date.today().year-30,date.today().year+1))
END_DATE_CHOICES = START_DATE_CHOICES
START_DATE_CHOICES = START_DATE_CHOICES.items()
START_DATE_CHOICES.sort()
START_DATE_CHOICES.reverse()
START_DATE_CHOICES = tuple(START_DATE_CHOICES)

END_DATE_CHOICES['current'] = 'current'
END_DATE_CHOICES = END_DATE_CHOICES.items()
END_DATE_CHOICES.sort()
END_DATE_CHOICES.reverse()
END_DATE_CHOICES = tuple(END_DATE_CHOICES)

#both schools and companies
class Institution(models.Model):
    name = models.CharField(max_length = 75)

class Education(models.Model):
    DEGREE_CHOICES = (
                      ('A.A.', 'Associate'),
                      ('Minor', 'Minor'),
                      ('B.A.', 'Bachelor of Arts'),
                      ('B.S.', 'Bachelor of Science'),
                      ('Masters', 'Masters'),
                      ('Ph. D.', 'Doctor of Philosophy'),
                      )
    school = models.ManyToManyField(Institution, through='Dates')
    degree = models.CharField(max_length = 5, choices = DEGREE_CHOICES, null = True)
    subject = models.CharField(max_length = 20, null = True)

class Work(models.Model):
    company = models.ManyToManyField(Institution, through='Dates')
    position = models.CharField(max_length = 50, null = True)
    jobDescription = models.TextField(null = True)

class Dates(models.Model):
    education = models.ForeignKey(Education, null = True)
    work = models.ForeignKey(Work, null = True)
    institution = models.ForeignKey(Institution)

    start = models.CharField(max_length = 4, choices = START_DATE_CHOICES)
    end = models.CharField(max_length = 7, choices = END_DATE_CHOICES)


class Person(models.Model):
    ....
    school = models.ManyToManyField(Institution, blank=True)
    education = models.ManyToManyField(Education, blank = True)
    company = models.ManyToManyField(Institution, blank = True, related_name="%(app_label)s_%(class)s_related")
    work = models.ManyToManyField(Work, blank=True)
    ....

所以我的问题是:这是一种可以接受的方式吗?我是新手,我不确定我是否只是在滥用关系

另外,我确信这是一个更简单的方法来完成整个开始/结束日期的事情......虽然不能解决这个问题

非常感谢任何指示,谢谢!

1 个答案:

答案 0 :(得分:1)

对于多对多的字段,您应该使用复数形式。对于Person,例如educationsjobs

此外,在模型字段中编写job_description而不是jobDescription也是惯例。

Person中,字段schoolcompany是多余的,因为可以通过educations(目前education)和jobs访问该信息(目前分别为work

我认为您不需要company中的多对多字段Work。一个简单的ForeignKey就足够了。我想你在一家公司只有特定的工作时间。您可以在多家公司同时从事多项工作,但仍然每个工作都在一个雇主身上。或者我错了吗?

Education也是如此。即使你在这个教育过程中去过几所学校,你也只有一所学校的特定科目的学位。或者您想要准确地模拟这种情况吗?

所有日期的命名都有点误导,因为它们都是特定年份。您也可以在NULL年末使用'current'并使用PositiveIntegerField

现在我有了这段代码:

#both schools and companies
class Institution(models.Model):
    name = models.CharField(max_length = 75)

class Education(models.Model):
    DEGREE_CHOICES = (
                      ('A.A.', 'Associate'),
                      ('Minor', 'Minor'),
                      ('B.A.', 'Bachelor of Arts'),
                      ('B.S.', 'Bachelor of Science'),
                      ('Masters', 'Masters'),
                      ('Ph. D.', 'Doctor of Philosophy'),
                      )
    school = models.ForeignKey(Institution)
    degree = models.CharField(max_length = 5, choices = DEGREE_CHOICES, null = True)
    subject = models.CharField(max_length = 20, null = True)
    start_year = models.PositiveIntegerField()
    end_year = models.PositiveIntegerField(null=True)

class Job(models.Model):
    company = models.ForeignKey(Institution)
    position = models.CharField(max_length = 50, null = True)
    job_description = models.TextField(null = True)
    start_year = models.PositiveIntegerField()
    end_year = models.PositiveIntegerField(null=True)


class Person(models.Model):
    ....
    educations = models.ManyToManyField(Education, blank = True)
    jobs = models.ManyToManyField(Work, blank=True)
    ....

当然,如果你想拥有多年的选择,你可以拥有它们

YEAR_CHOICES = ((year, str(year)) for year in range(...))

另外,您可以write a custom validator查看年份字段。