代码之家  ›  专栏  ›  技术社区  ›  Dave

在Django中,如何创建一个模型来存储对另一个模型的修改?

  •  0
  • Dave  · 技术社区  · 4 年前

    我使用的是Python 3.9和Django 3.2。我有以下型号

    class Coop(models.Model):
        objects = CoopManager()
        name = models.CharField(max_length=250, null=False)
        types = models.ManyToManyField(CoopType, blank=False)
        addresses = models.ManyToManyField(Address, through='CoopAddressTags')
        enabled = models.BooleanField(default=True, null=False)
        phone = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_phone')
        email = models.ForeignKey(ContactMethod, on_delete=models.CASCADE, null=True, related_name='contact_email')
        web_site = models.TextField()
        description = models.TextField(null=True)
        approved = models.BooleanField(default=False, null=True)
    

    我们想设置一种情况,有人可以提议对数据库中的一行进行更改,在保存之前会对其进行审查,所以我创建了这个结构

    class CoopChange(Coop):
        """
        """
        created_at = models.DateTimeField(null=False, default=datetime.now)
    

    问题是,当我创建迁移时,创建的表只是指向原始模型,而不是存储所有字段

            Table "public.directory_coopchange"
       Column    |           Type           | Modifiers 
    -------------+--------------------------+-----------
     coop_ptr_id | integer                  | not null
     created_at  | timestamp with time zone | not null
    

    这是不理想的,因为原始表将包含最终确定的条目和建议更改的条目。有没有一种方法可以创建一个实体,存储反映原始实体结构的拟议更改?

    0 回复  |  直到 4 年前
        1
  •  0
  •   Artisan    4 年前

    有几种方法可以解决这个问题

    1. 改变 Coop 到抽象基类: https://docs.djangoproject.com/en/4.0/topics/db/models/#abstract-base-classes

    然后您可以从中继承两个类 CoopProposed CoopApplied 你可以计算出创建每个

    1. 只需使用一个类 笼子 并添加一个名为 approved 默认为 False 然后将其设置为 True 当您批准更改时。 这可能不是您想要的,因为它将覆盖以前的任何更改,并且您可能希望保留更改的历史记录。

    2. 添加特性 proposed 作为Coop类上的JSONField(如果您使用的DB支持,请检查文档)。这可以存储一个完整的字典,其中包含所建议的更改的键和值。获得批准后,可以读取该字段,并将其应用于函数或类似函数中的模型属性。

    class Coop():
        objects = CoopManager()
        name = models.CharField(max_length=250, null=False)
        types = models.ManyToManyField(CoopType, blank=False)
        ...
        proposed = models.JSONField("Proposed Changes", null=True)
    
        def apply_proposed_changes(self):
           proposed = self.proposed
           self.name = proposed.get('name')
           for type in proposed.get('types'):
               self.types.add(CoopType.objects.get(name=type))
           ...
        
    

    在任何情况下,如果您试图从 笼子 您需要了解Django模型继承是如何工作的,以及所有的注意事项,然后才能深入了解: https://docs.djangoproject.com/en/4.0/topics/db/models/#model-inheritance

    推荐文章