Django是否应该实现DB

我有一个Django 1.3应用程序,我正在使用South 0.7.3进行数据库迁移。 我有一个问题, on_delete=models.SET_NULL规则似乎并没有在父实体被删除时触发,因此给我一个来自底层DB(即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

然后我阅读了Django文档中的on_delete规则,这些规则说明了(我的强调):

当被ForeignKey引用的对象被删除时,Django默认模拟 SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。 这种行为可以通过指定on_delete参数来覆盖。

“模拟”部分向我建议,Django试图自己实现on_delete行为,并且不依赖底层DB来自动执行这个事务作为事务的一部分,从而使得南方的bug无关紧要。

我在Django源代码中通过db/models/deletion.py来戳,并且基于SET() / SET_NULL()collect()它看起来像Django本身应该这样做,但是,如果我尝试为了从Django管理员中删除一个AccessPeriod,我在Payments表上为它仍然引用的ID取得约束违规,现在它被删除了,也就是说它看起来好像Django在Payment.period关系中调用SET_NULL()作为对accessPeriod.delete()的调用。

我在这里做错了什么,或者误解Django应该做什么? 试图避免手动黑客DB来插入ON DELETE规则,这感觉非常脆弱和可怕。


在我的具体情况中,我将这个bug追溯到我的models.py代码中的ModelAdmin内联的声明,导致我的模型类被错误地实例化,破坏的on_delete行为是最明显的副作用。 从我的提交信息:

修复了级联删除在Django DB中没有正确完成的问题。

事实证明,不要在models.py的全局范围内声明ModelAdmins,否则不同模型之间的所有关系都会在加载所有模型之前计算出来,并且大部分模型都会被忽略。 在Django文档中,真的没有那么强调这一点。

因此,在我最初的(破碎的)代码中,我会在每个模型的ModelAdmin后立即声明一个la:

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以便在处理所有模型声明之后,为每个类设置所有的metaclass设置,然后所有关系开始正常运行再次。

链接地址: http://www.djcxy.com/p/53613.html

上一篇: Is Django supposed to implement DB on

下一篇: Create a custom view using a nib and use it in a window