Mar*_*rty 261 python django django-models
我对Django很熟悉,但最近注意到on_delete=models.CASCADE
模型中存在一个选项,我搜索了相同的文档,但找不到更多:
在Django 1.9中更改:
on_delete
现在可以用作第二个位置参数(以前它通常只作为关键字参数传递).它将是Django 2.0中的必需参数.
from django.db import models
class Car(models.Model):
manufacturer = models.ForeignKey(
'Manufacturer',
on_delete=models.CASCADE,
)
# ...
class Manufacturer(models.Model):
# ...
pass
Run Code Online (Sandbox Code Playgroud)
on_delete做什么?(我想如果删除模型需要完成的操作)
怎么models.CASCADE
办?(文档中的任何提示)
还有哪些其他选择(如果我的猜测是正确的)?
这个文档在哪里?
Ant*_*ard 546
这是删除引用对象时要采用的行为.它不是django特有的,这是一个SQL标准.
发生此类事件时,可能会采取以下6种操作:
CASCADE
:删除引用的对象时,也删除引用它的对象(例如,当您删除博客文章时,您可能也想删除注释).SQL等价物:CASCADE
.PROTECT
:禁止删除引用的对象.要删除它,您必须删除手动引用它的所有对象.SQL等价物:RESTRICT
.SET_NULL
:将引用设置为NULL(要求该字段可以为空).例如,当您删除用户时,您可能希望保留他在博客帖子上发布的评论,但是说它是由匿名(或已删除)用户发布的.SQL等价物:SET NULL
.SET_DEFAULT
:设置默认值.SQL等价物:SET DEFAULT
.SET(...)
:设置给定值.这个不是SQL标准的一部分,完全由Django处理.DO_NOTHING
:可能是一个非常糟糕的主意,因为这会在数据库中创建完整性问题(引用实际上不存在的对象).SQL等价物:NO ACTION
.来源:Django文档
另请参阅PostGreSQL的文档.
在大多数情况下,CASCADE
是预期的行为,但是对于每个ForeignKey,你应该总是问自己在这种情况下的预期行为是什么.PROTECT
并且SET_NULL
通常很有用.设置CASCADE
不应该的位置,可以通过简单地删除单个用户来潜在地删除所有数据库.
him*_*229 37
该on_delete
方法用于告诉Django如何处理依赖于您删除的模型实例的模型实例.(例如ForeignKey
关系).该on_delete=models.CASCADE
告诉Django级联的删除效果,即继续删除相关模型为好.
这是一个更具体的例子.假设您有一个Author
模型ForeignKey
中的Book
模型.现在,如果删除Author
模型的实例,Django将不知道如何处理Book
依赖于该Author
模型实例的模型实例.该on_delete
方法告诉Django在这种情况下该怎么做.设置on_delete=models.CASCADE
将指示Django级联删除效果,即删除Book
依赖于Author
您删除的模型实例的所有模型实例.
注意:on_delete
将成为Django 2.0中的必需参数.在旧版本中,默认为CASCADE
.
Hel*_*enM 31
仅供参考,模型中的on_delete参数是从它听起来的倒退.您将"on_delete"放在模型上的外键(FK)上,告诉django如果删除了您在记录中指向的FK条目该怎么做.我们商店最常用的选项是PROTECT,CASCADE和SET_NULL.以下是我发现的基本规则:
以下是完成所有三件事的模型示例:
class PurchPurchaseAccount(models.Model):
id = models.AutoField(primary_key=True)
purchase = models.ForeignKey(PurchPurchase, null=True, db_column='purchase', blank=True, on_delete=models.CASCADE) # If "parent" rec gone, delete "child" rec!!!
paid_from_acct = models.ForeignKey(PurchPaidFromAcct, null=True, db_column='paid_from_acct', blank=True, on_delete=models.PROTECT) # Disallow lookup deletion & do not delete this rec.
_updated = models.DateTimeField()
_updatedby = models.ForeignKey(Person, null=True, db_column='_updatedby', blank=True, related_name='acctupdated_by', on_delete=models.SET_NULL) # Person records shouldn't be deleted, but if they are, preserve this PurchPurchaseAccount entry, and just set this person to null.
def __unicode__(self):
return str(self.paid_from_acct.display)
class Meta:
db_table = u'purch_purchase_account'
Run Code Online (Sandbox Code Playgroud)
作为最后一个消息,你知道如果你没有指定on_delete(或没有),默认行为是CASCADE吗?这意味着如果有人在您的性别表上删除了性别条目,则任何具有该性别的人员记录也会被删除!
我会说,"如果有疑问,请设置on_delete = models.PROTECT." 然后去测试你的应用程序.您将很快找出哪些FK应该标记其他值而不会危及您的任何数据.
此外,值得注意的是,on_delete = CASCADE实际上并未添加到任何迁移中,如果这是您选择的行为.我想这是因为它是默认值,所以把on_delete = CASCADE与什么都不做是一回事.
小智 14
简单来说,on_delete 是一条指令,指定在删除外来对象的情况下将对对象进行哪些修改:
CASCADE:当删除外来对象时,将删除子对象
SET_NULL:将子对象外键设置为 null
SET_DEFAULT:将子对象设置为创建模型时给定的默认数据
RESTRICT :RestrictedError
在某些条件下引发 a 。
PROTECT:只要有子对象继承自外来对象,就可以防止外来对象被删除
附加链接:
https://docs.djangoproject.com/en/4.0/ref/models/fields/#foreignkey
小智 7
如前所述,CASCADE将删除具有外键的记录,并引用另一个已删除的对象。因此,例如,如果您有一个房地产网站,并且有一个引用城市的房地产
class City(models.Model):
# define model fields for a city
class Property(models.Model):
city = models.ForeignKey(City, on_delete = models.CASCADE)
# define model fields for a property
Run Code Online (Sandbox Code Playgroud)
现在,当从数据库中删除城市时,所有关联的属性(例如位于该城市的房地产)也将从数据库中删除
现在,我还要提及其他选项的优点,例如SET_NULL或SET_DEFAULT甚至DO_NOTHING。基本上,从管理角度来看,您要“删除”这些记录。但是您真的不希望它们消失。出于很多原因。可能有人不小心删除了该文件,或者进行了审核和监视。和简单的报告。因此,这可能是一种将财产与城市“断开连接”的方式。同样,这将取决于您的应用程序的编写方式。
例如,某些应用程序的“已删除”字段为0或1。所有搜索和列表视图等内容,可能出现在报表中或用户可以从前端访问它的任何位置,均不包括deleted == 1
。但是,如果您创建自定义报告或自定义查询来下拉已删除记录的列表,甚至更多,以便查看上次修改的时间(另一个字段)以及由谁(即谁删除它以及何时删除)。从行政角度来看,这是非常有利的。
并且不要忘记,您可以像还原deleted = 0
那些记录一样简单地还原意外删除。
我的观点是,如果有功能,总会有其背后的原因。并非总是一个很好的理由。但这是一个原因。往往也是一个好人。
小智 7
这是您的问题的答案:为什么我们使用 on_delete?
当 ForeignKey 引用的对象被删除时,Django 默认模拟 SQL 约束 ON DELETE CASCADE 的行为,并删除包含 ForeignKey 的对象。可以通过指定 on_delete 参数来覆盖此行为。例如,如果您有一个可以为 null 的 ForeignKey 并且您希望在删除引用的对象时将其设置为 null:
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
Run Code Online (Sandbox Code Playgroud)
on_delete 的可能值可以在 django.db.models 中找到:
CASCADE:级联删除;默认值。
PROTECT:通过引发 ProtectedError(django.db.IntegrityError 的子类)来防止删除引用的对象。
SET_NULL:设置外键为空;这只有在 null 为 True 时才有可能。
SET_DEFAULT:将 ForeignKey 设置为其默认值;必须设置 ForeignKey 的默认值。
使用CASCADE意味着实际上告诉 Django 删除引用的记录。在下面的投票应用程序示例中:当“问题”被删除时,它也会删除此问题的选项。
例如 问题:您是如何得知我们的?(选择:1. 朋友 2. 电视广告 3. 搜索引擎 4. 电子邮件推广)
当您删除此问题时,它也会从表中删除所有这四个选项。 注意它流向哪个方向。您不必在问题模型中放入 on_delete=models.CASCADE 将其放入选择中。
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.dateTimeField('date_published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_legth=200)
votes = models.IntegerField(default=0)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
143700 次 |
最近记录: |