Hi All,
I've taken interest to implimenting built in django support of ON DELETE CASCADE. As a general concept, the ticket was accepted 3 years ago, and there was some discussion around that time:
https://code.djangoproject.com/ticket/21961 . I've put together a small PR with some but not all of the proposed design decisions,
https://github.com/django/django/pull/8661. The original ticket proposed adding something like models.DB_CASCADE in addition to models.CASCADE, models.SET_NULL. That is the tact that I took in the PR.
At the time of the ticket there were some concerns:
1. Q: What do we do with models.DB_CASCADE when using a DB that doesn't support it?
A: MySQL, PostgreSQL, SQLite3 and Oracle all now support this functionality.
2. Q: Won't it be confusing that signals will not fire?
A: We can document that the application code mimics models.DO_NOTHING, no signals will fire, and that all the deletion will be handled by SQL.
3. Q: Won't it be confusing that models.DB_CASCADE won't trigger a foreign model's models.CASCADE?
A: Is it any different than having a models.DO_NOTHING table pointing to a models.CASCADE table? We can document that on the application side, models.DB_CASCADE works like models.DO_NOTHING.
4. Q: generic foreign keys?
A: We could forbid models.DB_CASCADE on these types of relations?
5. Q: implicit foreign keys between child to parent in model inheritance?
A: We could forbid models.DB_CASCADE on these types of relations?
Additionally there was a proposal by Carl Meyer to split out database based delete into a separate kwarg. To summarize: ForeignKey(on_delete=models.CASCADE) versus ForeignKey(on_delete_db=models.DB_CASCADE). This would help avoid having to implement a magical fallback mode when the DB didn't support models.DB_CASCADE. It also would help eliminate two very different code paths overloading the same kwarg.
My thoughts on the above splitting of the kwargs:
All of the django 2.0 databases can support ON DELETE CASCADE. So there's no longer any need for a magical fall back mode. There's also the added burden on explaining that we can only pass one of the two kwargs, and not use both at the same time. I think that favors overloading a single kwarg.
Simon Charrette made a suggestion to make the models.CASCADE, models.SET_NULL, models.DB_CASCADE, etc all inherit from an OnDelete class. This allows the old application callables to still be simple callables, new SQL based operations such as DB_CASCADE to access an as_sql method, and yet both be instances of the same class for migration serialization.
Seeking feedback,
Nick