I am trying to restrict GFK to be pointed to objects of a few models only, and I thought CheckConstraint will be a great way to do this, however I get this error
It is not possible to achieve this using the CheckConstraint
functionality. Django translates all ORM commands to the low level DB specific commands, and such constraint creation isn't possible even on the DB level. In fact, we can apply CheckConstraint
to a single row beeing added/updated only.
The note in documentation on PostgreSQL
says:
PostgreSQL does not support CHECK constraints that reference table data other than the new or updated row being checked. While a CHECK constraint that violates this rule may appear to work in simple tests, it cannot guarantee that the database will not reach a state in which the constraint condition is false (due to subsequent changes of the other row(s) involved). This would cause a database dump and reload to fail. The reload could fail even when the complete database state is consistent with the constraint, due to rows not being loaded in an order that will satisfy the constraint. If possible, use UNIQUE, EXCLUDE, or FOREIGN KEY constraints to express cross-row and cross-table restrictions.
If what you desire is a one-time check against other rows at row insertion, rather than a continuously-maintained consistency guarantee, a custom trigger can be used to implement that. (This approach avoids the dump/reload problem because pg_dump does not reinstall triggers until after reloading data, so that the check will not be enforced during a dump/reload.)
So, the only way to introduce desired constrains is using db triggers. You can create empty migration and add DB trigger into it.