It is possible through generic relations , something like this:
content_type = models.ForeignKey(ContentType) object_id = models.IntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id')
But, it seems, there is no sensible method to restrict what GFK can refer to, except that in the database a post-factum (after filling in the content_types table) to thrust the constraints by ID to insure.
Another option is through multi-table inheritance .
class MenuItem(models.Model): title = ... link = ... class Page(MenuItem): text = ... ...
But, again, ugly - MenuItem.objects
returns objects of the class MenuItem
, not Page
. Those. have to choose separately for each table and glue.
The third option is if the DBMS is able to inherit (like, say, PostgreSQL ), then use it and raw SQL.
CREATE TABLE menu_items ( ... ); CREATE TABLE pages ( ...) INHERITS (menu_items);
Then SELECT * FROM menu_items
can use all fields from descendant tables. But, again, this is ugly - we rush past Django's ORM. Although it is possible to get out through unmanaged models and, possibly, views for SELECT ... FROM ONLY ...
(if they are needed; since the ORM will never generate a query).
The fourth option is to have two ForeignKey
, page
and category
, and set the constraint that one and only one of them should be NULL
( None
). And to make, for convenience, @property
for a model that returns what is not None
. For me, this is the best option, but it is completely unsuitable for situations where there are many types of objects.