【问题标题】:How to re-assign ForeignKey in Django如何在 Django 中重新分配 ForeignKey
【发布时间】:2015-02-15 03:53:05
【问题描述】:

我有以下两种型号:

 class Student(models.Model):
     name = models.CharField(max_length=255, help_text='Name of student')

 class Group(models.Model):
         name = models.CharField(max_length=255, help_text="Groups' name")
         elder = models.ForeignKey(Student, default=None, blank=True, null=True)

情况是我有表单(从 m​​odelForm 创建),它能够更新数据库中的条目。我的问题如下: 用户可以使用 ForeignKey 创建两个组,它们将指向 Student 表中的一个条目。

我在文档中找到了db_constraint,但这似乎还不够。 获得以下行为会很棒: 当用户分配已分配给另一个模型的 ForeignKey 时,我想删除旧分配并创建新分配。所以Student外键一次只能分配给一个模型。

【问题讨论】:

    标签: python django django-models django-forms


    【解决方案1】:

    OneToOneField 专为独特的关系而设计:

    class Group(models.Model):
        name = models.CharField(max_length=255, help_text="Groups' name")
    
    class Student(models.Model):
        name = models.CharField(max_length=255, help_text='Name of student')
        group = models.OneToOneField(Group, default=None, blank=True, null=True, related_name='elder')
    

    请注意我是如何将关系字段移至 Student 模型的,这将为您提供所需的行为。如果它在Group 模型上,并且您将一个学生分配到一个新组,而他已经有一个,它将引发DatabaseError 违反unique 约束。在这种情况下,(唯一的)FOREIGN KEY 列位于Student 的表中,因此如果您将学生分配到另一个组并保存该组,则会更新学生表并替换旧组。

    【讨论】:

      【解决方案2】:

      覆盖Groupsave方法:

      def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
           Group.objects.filter(elder.self.elder).update(elder=None)
           super(Group, self).save(force_insert, force_update, using, update_fields)
      

      但你必须使用事务以避免不一致

      【讨论】:

      • 感谢您的想法。我决定不添加诸如覆盖内置方法之类的复杂性,而只需将此查询 Group.objects.filter(elder_id=new_elder.id).update(elder=None) 预先保存表单即可完美运行。
      • 在 django 中覆盖 save() 很常见。 “内部”方法是 save_base()
      猜你喜欢
      • 1970-01-01
      • 2017-05-03
      • 2012-03-26
      • 2015-09-23
      • 1970-01-01
      • 2019-03-16
      • 2015-10-13
      • 2011-08-11
      • 2020-12-17
      相关资源
      最近更新 更多