Django Model Inheritance And Foreign Keys Django Model Inheritance And Foreign Keys django django

Django Model Inheritance And Foreign Keys


You could also do a generic relation http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1 and check the types to constrain it to B or C when setting or saving. This is probably more work than figuring out the direct reference, but might feel cleaner.


One way to do this is to add an intermediate class as follows:

class A(Model):    class Meta(Model.Meta):        abstract = True    # common definitions hereclass Target(A):    # this is the target for links from D - you then need to access the     # subclass through ".b" or ".c"    # (no fields here)class B(Target):    # additional fields hereclass C(Target):    # additional fields here        class D(A):    b_or_c = ForeignKey(Target)    def resolve_target(self):        # this does the work for you in testing for whether it is linked         # to a b or c instance        try:            return self.b_or_c.b        except B.DoesNotExist:            return self.b_or_c.c

Using an intermediate class (Target) guarantees that there will only be one link from D to either B or C. Does that make sense? See model inheritance for more information.

In your database there will be tables for Target, B, C and D, but not A, because that was marked as abstract (instead, columns related to attributes on A will be present in Target and D).

[Warning: I have not actually tried this code - any corrections welcome!]


From the Django Docs:

For example, if you were building a database of "places", you would build pretty standard stuff such as address, phone number, etc. in the database. Then, if you wanted to build a database of restaurants on top of the places, instead of repeating yourself and replicating those fields in the Restaurant model, you could make Restaurant have a OneToOneField to Place (because a restaurant "is a" place; in fact, to handle this you'd typically use inheritance, which involves an implicit one-to-one relation).

Normally, you would just have Restaurant inherit from Place. Sadly, you need what I consider a hack: making a one-to-one reference from subclass to superclass (Restaurant to Place)