草庐IT

python - on_delete 对 Django 模型有什么作用?

coder 2023-04-28 原文

我对 Django 非常熟悉,但我最近注意到存在一个 on_delete=models.CASCADE与模型选项。我已经搜索了相同的文档,但除了以下内容之外我什么也找不到:

Changed in Django 1.9:

on_delete can now be used as the second positional argument (previously it was typically only passed as a keyword argument). It will be a required argument in Django 2.0.


An example case of usage is :
from django.db import models

class Car(models.Model):
    manufacturer = models.ForeignKey(
        'Manufacturer',
        on_delete=models.CASCADE,
    )
    # ...

class Manufacturer(models.Model):
    # ...
    pass
on_delete 有什么作用? (我猜如果模型被删除了要执行的操作。)
什么models.CASCADE做? (文档中的任何提示)
还有哪些其他选项可用(如果我的猜测是正确的)?
这方面的文档在哪里?

最佳答案

这是删除引用对象时要采用的行为。它不是 Django 特有的;这是一个 SQL 标准。尽管 Django 在 SQL 之上有自己的实现。 (1)
发生此类事件时,可以采取七种可能的操作:

  • CASCADE :当引用的对象被删除时,也删除引用它的对象(例如,当您删除博客文章时,您可能还想删除评论)。 SQL 等效项:CASCADE .
  • PROTECT : 禁止删除引用的对象。要删除它,您必须手动删除所有引用它的对象。 SQL 等效项:RESTRICT .
  • RESTRICT :(在 Django 3.1 中引入)与 PROTECT 类似的行为匹配 SQL 的 RESTRICT更精确地。 (见 django documentation example)
  • SET_NULL : 将引用设置为 NULL(要求该字段可以为空)。例如,当您删除一个用户时,您可能希望保留他在博客帖子上发表的评论,但假设它是由匿名(或已删除)用户发表的。 SQL 等效项:SET NULL .
  • SET_DEFAULT :设置默认值。 SQL 等效项:SET DEFAULT .
  • SET(...) : 设置给定值。这不是 SQL 标准的一部分,完全由 Django 处理。
  • DO_NOTHING :可能是一个非常糟糕的主意,因为这会在您的数据库中造成完整性问题(引用一个实际上不存在的对象)。 SQL 等效项:NO ACTION . (2)

  • 来源:Django documentation
    另见 the documentation of PostgreSQL例如。
    大多数情况下,CASCADE是预期的行为,但是对于每个外键,您应该始终问自己在这种情况下的预期行为是什么。 PROTECTSET_NULL经常有用。设置 CASCADE在不应该的地方,可以通过简单地删除单个用户来潜在地级联删除所有数据库。

    澄清级联方向的附加说明
    有趣的是注意到 CASCADE 的方向许多人不清楚行动。实际上,注意到 很有趣。只有 CASCADE Action 不清楚。我知道级联行为可能会令人困惑,但是您必须认为 它与任何其他 Action 的方向相同 .因此,如果您觉得 CASCADE方向你不清楚,实际上意味着on_delete你的行为不清楚。
    在您的数据库中,外键基本上由一个整数字段表示,该字段的值是外对象的主键。假设您有一个条目 评论_A ,它有一个条目的外键 文章_B .如果您删除条目 评论_A , 一切顺利。 文章_B 以前没有生活过评论_A 如果它被删除了,不要打扰。但是,如果删除 文章_B ,然后 评论_A panic !它从来没有离开过 文章_B 并且需要它,它是其属性的一部分( article=article_B ,但什么是 article_B ???)。这是哪里on_delete介入,以确定如何解决此完整性错误,或者说:
  • “不!求求你!不要!没有你我​​活不下去!” (在 Django/SQL 中被称为 PROTECTRESTRICT)
  • “好吧,如果我不是你的,那我就是别人的”(也就是 SET_NULL)
  • “再见世界,我不能没有文章_B”并自杀(这是CASCADE行为)。
  • “没关系,我有空余情人,我从现在开始引用文章_C”( SET_DEFAULT ,甚至 SET(...) )。
  • “我无法面对现实,我会一直呼唤你的名字,即使这是我唯一的事!” ( DO_NOTHING )

  • 我希望它使级联方向更清晰。 :)

    脚注

    (1) Django has its own implementation on top of SQL. And, as mentioned by @JoeMjr2 in the comments below, Django will not create the SQL constraints. If you want the constraints to be ensured by your database (for instance, if your database is used by another application, or if you hang in the database console from time to time), you might want to set the related constraints manually yourself. There is an open ticket to add support for database-level on delete constrains in Django.


    (2) Actually, there is one case where DO_NOTHING can be useful: If you want to skip Django's implementation and implement the constraint yourself at the database-level.

    关于python - on_delete 对 Django 模型有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38388423/

    有关python - on_delete 对 Django 模型有什么作用?的更多相关文章

    1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

      类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

    2. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

      很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

    3. ruby-on-rails - rails : keeping DRY with ActiveRecord models that share similar complex attributes - 2

      这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby​​类,但是我如何得到ActiveRecord关联这个类模型

    4. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

      我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

    5. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

      作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

    6. ruby-on-rails - unicode 字符串的长度 - 2

      在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

    7. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

      如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

    8. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

      关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

    9. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

      我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

    10. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

      我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

    随机推荐