Csa*_*oth 7 python django foreign-key-relationship
class Basket:
name = models.CharField(max_length=50, blank=True, null=True)
class Apple:
name = models.CharField(max_length=50, blank=True, null=True)
basket = models.ForeignKey(Basket, on_delete=models.PROTECT)
Run Code Online (Sandbox Code Playgroud)
...
myapple = new Apple(name="my")
myapple.save()
Run Code Online (Sandbox Code Playgroud)
...
auto_created_basket = myapple.basket
myapple.basket = existing_basket
auto_created_basket.delete()
Run Code Online (Sandbox Code Playgroud)
我尝试将 auto_created_basket 换成另一个,但当我尝试删除它时出现错误。
"Cannot delete some instances of model 'Basket' because they are referenced through a protected foreign key: 'Apple.basket'", [<Apple: My apple>])
在您的Apple模型中,该basket字段是外键
basket = models.ForeignKey(Basket, on_delete=models.PROTECT)
Run Code Online (Sandbox Code Playgroud)
其on_delete属性值明确规定通过防止删除篮子来保护苹果,即只要篮子里还有苹果就不能删除。
正如官方文档所说
当删除ForeignKey引用的对象时,Django默认模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。
和
PROTECT 参数通过引发 ProtectedError 来防止删除引用的对象
因此,最简单的步骤应该是删除on_delete参数并采用默认行为
basket = models.ForeignKey(Basket)
Run Code Online (Sandbox Code Playgroud)
但是,请查看外键模型字段的所有可能参数,并选择适合您的应用程序/场景要求的组合。
更新:
最近的 Django 版本需要on_delete. 只是不要删除它并添加您想要的参数(例如on_delete=models.CASCADE)。
我不想回答我的问题,但我的例子太简单了。答案非常好。
在实际的产品中,涉及到post_save信号,负责创建例如auto_created_basket。
问题是,当我说myapple.basket = existing_basketDjango 的层很好时,但数据库仍然保留对旧关系的引用。我的解决方案是在再次auto_created_basket.delete()保存后移动。myapple