gpt4 book ai didi

django - Django 是否应该自己实现 DB on_delete 规则?

转载 作者:行者123 更新时间:2023-12-04 12:36:41 25 4
gpt4 key购买 nike

我有一个 Django 1.3 应用程序,我使用 South 0.7.3 进行数据库迁移。我有一个问题 on_delete=models.SET_NULL删除父实体时,规则似乎没有触发,从而使我违反了底层数据库(即 Postgres 8.4)的约束。

实体定义的相关部分是:

class AccessPeriod:
....

class Payment:
period = models.ForeignKey(
AccessPeriod, related_name = "payments", db_index = True,
null = True, on_delete = models.SET_NULL )

经过一番挖掘,我发现 South 实际上并没有插入 ON DELETE子句到它为迁移生成的 SQL 中,因此数据库绝对不会对损坏的关系本身进行无效化:

http://south.aeracode.org/ticket/763

然后我阅读了 on_delete 规则的 Django 文档,其中说明(我的重点):

When an object referenced by a ForeignKey is deleted, Django by default emulates the behavior of the SQL constraint ON DELETE CASCADE and also deletes the object containing the ForeignKey. This behavior can be overridden by specifying the on_delete argument.



“模拟”部分向我建议 Django 尝试自己实现 on_delete 行为,并且不依赖底层数据库自动执行它作为事务的一部分,从而使 South 错误无关紧要。

我戳穿了 db/models/deletion.py在 Django 源代码中,基于 SET() 的实现/ SET_NULL()collect()看起来 Django 应该自己做这件事,但是,如果我尝试从 Django 管理员中删除 AccessPeriod,我会在 Payments 表上发现它仍然引用的 ID 的约束违规,现在已删除,即它没有似乎 Django 正在调用 SET_NULL()Payment.period作为对 accessPeriod.delete() 的调用的一部分的关系.

我在这里做错了什么,还是误解了 Django 应该做什么?只是试图避免手动破解数据库以自己插入 ON DELETE 规则,这感觉非常脆弱和可怕。

最佳答案

在我的特定情况下,我将此错误追溯到我的 models.py 代码中内联 ModelAdmin 的声明,导致我的模型类被错误地实例化,并损坏 on_delete行为最明显的副作用。从我的提交消息:

Fixed issue with cascading deletes not being done properly in Django DB.

Turns out it's really important to not declare your ModelAdmins at the global scope in models.py, otherwise all the relationships between the different models get calculated before all the models are loaded and lots of them get left out. Really isn't that emphatic about this in the Django documentation.



因此,在我的原始(损坏的)代码中,我会立即为每个模型声明 ModelAdmin,即:
class AccessPeriod( models.Model ):
....

class AccessPeriodAdmin( models.ModelAdmin ):
....

# This causes the metaclass setup for AccessPeriod to happen right now,
# and since related models for AccessPeriod are not all declared yet,
# relationship handling behaviour becomes broken for AccessPeriod
admin.site.register( AccessPeriod, AccessPeriodAdmin )

class Payment( models.Model ):
....

class PaymentAdmin( models.ModelAdmin ):
....

# Same effect on the Payment model here
admin.site.register( Payment, PaymentAdmin )

解决方案是将所有 ModelAdmin 声明移出 myapp/models.py并进入 myapp/admin.py这样每个类的所有元类设置都在处理完所有模型声明之后发生,然后所有关系再次开始正常运行。

关于django - Django 是否应该自己实现 DB on_delete 规则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6650499/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com