【问题标题】:How to write a self referencing Django Model?如何编写一个自引用的 Django 模型?
【发布时间】:2020-03-16 05:55:16
【问题描述】:

我有一个 Django 模型“Inspection”,它有:

InspectionID (PK)
PartID
SiteID
Date
Comment
Report
Signiture

我希望能够在检查 ID 和日期之间建立一对多的关系。因此,一个 ID 可以在多个日期进行检查。我该怎么做?我目前有以下:

class Inspection(models.Model):
    InspectionID = models.IntegerField(primary_key=True, unique=True)
    PartID = models.ForeignKey('Part', on_delete=models.CASCADE)
    SiteID = models.ForeignKey('Site', on_delete=models.CASCADE)
    Date = models.DateField(auto_now=False, auto_now_add=False)
    Comment = models.CharField(max_length=255, blank=True)
    Report = models.FileField(upload_to='docs', null=True, blank=True)
    Signiture = models.CharField(max_length=255, blank=True)

我考虑过使用models.ForeignKey,但我真的不知道在这种情况下如何正确实施。

【问题讨论】:

    标签: python django django-models database-design foreign-keys


    【解决方案1】:

    我希望能够在检查 ID 和日期之间建立一对多的关系。

    您创建一个额外的模型,例如:

    class InspectionDate(models.Model):
        inspection = models.ForeignKey(
            Inspection,
            on_delete=models.CASCADE,
            related_name='inspectiondates'
        )
        date = models.DateField()

    因此,您可以为给定的Inspection 创建InspectionDates。

    或者如果您想添加额外的数据,最好定义一个InspectionGroup 模型:

    class InspectionGroup(models.Model):
        pass
    
    class Inspection(models.Model):
        id = models.AutoField(primary_key=True, unique=True, db_column='InspectionId')
        inspectiongroup = models.ForeignKey(InspectionGroup, on_delete=models.CASCADE, db_column='InspectionGroupId')
        part = models.ForeignKey('Part', on_delete=models.CASCADE, db_column='PartId')
        site = models.ForeignKey('Site', on_delete=models.CASCADE, db_column='SiteId')
        date = models.DateField(db_column='Date')
        comment = models.CharField(max_length=255, blank=True, db_column='CommentId')
        report = models.FileField(upload_to='docs', null=True, blank=True, db_column='ReportId')
        signiture = models.CharField(max_length=255, blank=True, db_column='Signature')

    注意:属性名称一般写成snake_case [wiki],而不是PerlCase camelCase.

    【讨论】:

    • 嗯,好的。所以我无法在一个模型中做到这一点?如果我想在每个检查日期中包含评论/报告/签名,这是否也需要与检查日期而不是检查分组?
    • @Cm1602: 但是你会做一个InspectionGroup,然后把Inspections放在它下面。通过引用另一个Inspection,您创建了一个复杂的结构。例如说有三个相关的检查ABC。那么你如何将这些联系起来,将B链接到A,将C链接到B,或者两者都链接到A
    • 我有点明白为什么在这里有两个模型会有所帮助......我想让“InspectionID”成为将它们链接在一起的属性。 ID 与“SiteID”和“PartID”保持不变。但是每个检查项目的日期都会有评论/报告/签名。
    • @Cm1602: 但由于InspectionID是主键,你不能在多条记录上使用相同的id。主键应该是唯一的。通常这是由数据库强制执行的。
    • 因此,在这种情况下,我需要一种方法,即在检查标语下只有多个检查内容实例。因此,一个检查实例包含其他两个 ID,具有多个带有外键“日期”的“内容”对象。像这样的东西有用吗?
    【解决方案2】:

    您可以将 'self Foriegnkey' 存储为

    class Inspection(models.Model):
        InspectionID = models.IntegerField(primary_key=True, unique=True)
        PartID = models.ForeignKey('Part', on_delete=models.CASCADE)
        SiteID = models.ForeignKey('Site', on_delete=models.CASCADE)
        Date = models.DateField(auto_now=False, auto_now_add=False)
        Comment = models.CharField(max_length=255, blank=True)
        Report = models.FileField(upload_to='docs', null=True, blank=True)
        Signiture = models.CharField(max_length=255, blank=True)
        inspection_id = models.ForeignKey('self', null=True, blank=True)
    

    【讨论】:

    • 这不是引用整个 Inspection 对象吗?这意味着 InspectionID 不再是唯一的,因为它重复了多次。这只会让我将检查与不同的 ID 联系起来,这是我不想做的。
    猜你喜欢
    • 2023-02-24
    • 2012-09-20
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    相关资源
    最近更新 更多