【问题标题】:Review my Django Model - Need lots of suggestions查看我的 Django 模型 - 需要很多建议
【发布时间】:2009-12-01 22:49:01
【问题描述】:

我正在提取各种信息源来建立一个人的档案。一旦我这样做了,我想灵活地以不同的方式看待一个人。我在 django 方面没有很多经验,所以我想对我的模型进行批评(要温柔)。诚然,即使在我编写此代码时,我也在考虑冗余(反对 DRY),但我想知道其他人的想法。 FWIW - 这些数据是拉而不是创建的 - 所以也许我不应该保留它,但删除数据似乎很糟糕..

具体来说,我想知道使用多对多是否合适,或者您是否会亲吻并将每个条目保留为自己的,而不需要任何多对多业务。从长远来看,我认为 KISS 会使更新它变得简单(一个基本的 for 循环),但是在能够查询一个人(比如基于 location_description 或 job_function)方面存在权衡。无论如何,我会很感激一些意见。

class Person(models.Model):

    """This simply builds a notes user"""

    aliases = models.ManyToManyField(Aliases)  #Hmm this is list..
    assistant = models.CharField(max_length = 255, blank = True)
    cell_phone = models.CharField(max_lenth = 16, blank = True)
    city = models.ManyToManyField(City)
    country = models.ManyToManyField(County)
    department = models.ManyToManyField(Department)
    departmeht_number = models.ManyToManyField(Department_Number)
    division_code = models.ManyToManyField(Division_Code)
    email = models.EmailField(max_length = 50)
    functional_area = models.ManyToManyField(Functional_Area)
    # jpeg = models.
    job_classification = models.ManyToManyField(Job_Classification)
    job_classification_code = models.ManyToManyField(Job_Classification_Code)
    last_name = models.CharField(max_length = 255)
    location_description = models.ManyToManyField(Location_Description)
    location_path = models.ManyToManyField(Location_Path)
    mail_address = models.CharField(max_length = 255, blank = True)
    mail_domain = models.ManyToManyField(Mail_Domain)
    mail_file = models.CharField(max_length = 255, blank = True)
    mail_server = models.ManyToManyField(Mail_Server)
    match_pct = models.CharField(max_lenth = 6)
    name = models.CharField(max_length = 255)
    name_reverse = models.CharField(max_length = 255)
    nickname = models.CharField(max_length = 32)
    notes_url = models.URLField()
    #    object_class = models.
    office_phone = models.CharField(max_length = 255, blank = True)
    other_phone = models.CharField(max_length = 255, blank = True)
    position = models.ManyToManyField(Position)
    section = models.ManyToManyField(Section)
    section_code = models.ManyToManyField(SectionCode)
    shift = models.ManyToManyField(Shift)
    state = models.ManyToManyFiedl(State)
    supervisor = models.ManyToManyField(Supervisor)
    supervisor_reverse = models.ManyToManyField(Supervisor_reverse)
    uid = models.CharField(max_length = 128)

    def __unicode__(self):
        return str(self.name)

【问题讨论】:

  • 在仔细考虑对象层次结构后,通常这样的事情可以归结为很多。
  • 我认为您应该在此处将 KISS 定义为“有用块中的细分信息”。它将导致用于选择、过滤……的良好对象层次结构以及具有较少 NULL 值的打包数据库。
  • vikingosegundo - 好建议 - 我遵循大多数人的建议。但是越来越少的空值不断回来!谢谢

标签: django django-models coding-style python


【解决方案1】:

__unicode__ 应该返回 unicode

def __unicode__(self):
       return u'%s' %self.name

Django 为完整地址提供了一个电子邮件字段:

mail = models.EmailField()

我认为,地址模型可能是有意义的。一个人可以有多个地址(工作、家庭……)

编辑

我刚刚看到,您正在使用电子邮件字段。

这是干什么用的:

mail_address = models.CharField(max_length = 255, blank = True)
mail_domain = models.ManyToManyField(Mail_Domain)
mail_file = models.CharField(max_length = 255, blank = True)
mail_server = models.ManyToManyField(Mail_Server)

?

编辑

您不必一直使用 ManyToManyFields。查看 ForeignKey、OneToOneField 和通用框架

【讨论】:

  • 这很好 - 要回答您的问题,这必须是我从 ldap 中提取的一些数据。这对我来说毫无意义,但也许对其他人来说。到目前为止,我一直非常不愿意扔掉我拥有的数据,但我开始改变我的立场了。
  • 一旦你需要它,你添加一个带有外键的 LDAPUser 模型给用户。
【解决方案2】:

在我看来,您的许多 ManyToMany 关系应该由目标模型的属性替换。

例如,您将 citycountry 作为单独的关系。这意味着您最终可能会得到一个拥有city = ['Paris', 'London', 'New York']country = ['USA', 'France', 'UK'] 的用户。

相反,我认为您应该设置一个locations ManyToMany 关系,指向一个由citycountry 属性组成的模型。

departmentdepartment_numberjob_classificationjob_classification_codelocation_descriptionlocation_path等一样

编辑:在某些情况下,您可能可以使用 ForeignKey 而不是 ManyToMany。也许一个用户只能属于citycountry之一?

Positionsupervisor 可能是一些更棘手的关系,因为position 应该指向一个部门/单位,而is_supervisor 应该是一个职位的属性。也就是说,您只需要指向一个职位,因为主管将从其他用户的职位中检索。

编辑:示例:如果 A 人在 X 部门工作,B 人也在 X 部门工作,但作为经理,那么 A 人由 B 人监督。

编辑:很容易假设一个部门只能有一个经理,或者一个经理只能管理一个部门。我建议不要这样做,因为组织经常有各种特殊情况。想一想当经理离开公司时,部门会暂时没有经理,还是会暂时由另一位经理接任,从而保留两个经理职位。

【讨论】:

  • 哇——这真是个好东西。没有人会被附加到一个物理位置,所以我的多对多关系错了吗?根据您的职位/主管观察,您是对的。谢谢!!
  • 抱歉这么晚才回复 — 是的,如果一个人只能在物理位置上,您应该使用 ForeignKey。 ManyToMany 意味着每个人可以有很多位置,每个位置可以有多个人连接到它。
【解决方案3】:

这里有一些想法。

我认为您应该为departmentjob_classification 等创建单独的模型。例如

class department(models.Model):
    name = Models.CharField(max_length=100)
    number = Models.IntegerField

然后有一个ManyToManyField 到部门。否则,如果你有department = ['HR', 'Finance']department_number = [12, 5]的人,我认为没有办法分辨哪个部门编号代表哪个部门。

如果字段按其描述的内容进行分组,而不是按字母顺序排列,我会发现模型更易于阅读。 E.G 我认为namenicknamelast_name 应该一起定义。

最后,也许 Alias 应该是一个单独的模型,从 ForeignKeyPerson,因为只有一个人应该有任何特定的别名。

【讨论】:

  • 肯定会这样做。它具有很好的逻辑意义。谢谢!
【解决方案4】:

我会创建从属字段并删除主管。

 subordinates = models.ManyToManyField('self', related_name='supervisors', through=Position)

这样主管将是一个自动反向查找字段,并且将有一个职位记录将主管与下属联系起来

编辑:实际上我还建议仔细考虑重新设计模型。也许你不需要你建议的那么多。

看起来你有“部门”、“公司”(如果你需要跟踪多家公司)、“职位”、“地点”和“人”……决定要保留哪些大实体,然后想想具体在哪里每个字段都属于以及如何链接将转换为表格的“大”对象。

可能最好在Position对象之间建立下属-上级关系,因为人来人往,但职位更永久。所以我有:

class Position:
    title = models.CharField() #product manager, engineer, etc.
    employee = models.ForeignKey(Person, related_name='positions')
    subordinates = models.ManyToManyField('self', related_name='supervisors')

如果每个职位不需要多个主管,请使用

    supervisor = models.ForeignKey('self', related_name='subordinates')

即使现在没有 subordiantes 字段,也可以像以前一样通过相关名称访问它。

位置属于哪里?

如果您决定 Person 和 Department 都必须有位置,那么您可能会想到通用关系,尽管它不像“常规关系”那么容易使用,但您也可以通过添加“类型”来避免location ('private/business'),然后使用 Location.company 或 Location.residence_owner 并避免使用泛型关系。

【讨论】:

  • 我终于打到了这个。感谢他们使用的建议!
【解决方案5】:

我还建议您使用单独的就业模式。使用外键返回您的 Person 对象。您可以根据需要向该表添加尽可能多的记录。

同样的建议也适用于 mail_* 字段。

【讨论】:

    猜你喜欢
    • 2022-07-13
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    相关资源
    最近更新 更多