开发者

Where is the ON DELETE CASCADE logic being implemented in Django? (PostgreSQL is used)

I just need a confirmation for my understanding on Django's implementation of ON DELETE CASCADE from you Django experts.

According to the official Django documentation:

When Django deletes an object, by default it emulates the behavior of the SQL constraint ON DELETE CASCADE -- in other words, any objects which had foreign keys pointing at the object to be deleted will be deleted along with it.

Does the word "emulate" imply that the ON DELETE CASCADE logic is actually implemented in Django instead of at the data开发者_如何转开发base level? (I looked into my database and all the tables that contains foreign keys have ON DELETE NO ACTION in their definitions.)

If my understanding is correct, is there any way that I can relocate the ON DELETE CASCADE logic from the app layer to the database layer? I am more looking for a proper way, not an hack, of doing this. (Note: I am using PostgreSQL as my backend.)


If you are asking where the relevant code is implemented: You can find it here.

Implementing the CASCADE-DELETE logic in the application/ORM layer makes sense as this enables the app to get informed when deletion happens (eg. Django's delete signals are fired for the deleted instances), furthermore it is a sane way to enable this feature across different types of databases.

If you are worried about the integrity of your data: Django still sets foreign key constraints if your database supports this (eg. check Postgresql). So your database won't let you delete any rows a foreign key is pointing to.

Try it yourself:

> DELETE FROM accounts_publisher WHERE id=5;
ERROR:  update or delete on table "accounts_publisher" violates foreign key constraint "accounts_publisher_id_411559b18a178e73_fk_accounts_publisher_id" on table "accounts_membership"
DETAIL:  Key (id)=(5) is still referenced from table "accounts_membership".


FYI, this has been configurable since django 1.3: https://docs.djangoproject.com/en/1.6/ref/models/fields/#django.db.models.ForeignKey.on_delete

Basically you need to set on_delete to DO_NOTHING and add the cascade logic to the DB yourself:

DO_NOTHING: Take no action. If your database backend enforces referential integrity, this will cause an IntegrityError unless you manually add a SQL ON DELETE constraint to the database field (perhaps using initial sql).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜