Alex Rivera | Logout

Abstract Models and Foreign Keys in Django

Asked 2011-09-23T17:31:14.403
10

I am working on a django project in which I create a set of three abstract models that I will use for a variety of apps later on. The problem I am running into is that I want to connect those models via ForeignKey but django tells me that it can't assign foreignkeys to an abstract model.

My current solution is to assign foreignkeys when I instanciate the class in my other apps. However, I am writing a Manager for the abstract classes (book and pages) right now and would need to access these foreignkeys. What I am basically trying to do is to get the number of words a book has in a stateless manner, hence without storing it in a field of the page or book.

The model looks similar to this:

class Book(models.Models):
    name = models.CharField(...)
    author = models.CharField(...)
    ...

    class Meta:
        abstract = True

class Page(models.Models):
    book = models.ForeignKey(Book)
    chapter = models.CharField(...)
    ...

    class Meta:
        abstract = True

class Word(models.Models):
    page = models.ForeignKey(Page)
    line = models.IntegerField(...)
    ...

    class Meta:
        abstract = True

Note that this model here is just to give an example of what I am trying to do, hence whether this model (Book-Page-Word) makes sense from an implementation standpoint is not needed.

Edit
Report

1 Answer

13

Maybe what you need here is a GenericForeignKey, since you don't actually know what model your ForeignKeys will point to? That means that you'll loose some of the "type-safety" guarantees of a normal relation, but it will allow you to specify those relationships in a more general way. See https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#django.contrib.contenttypes.generic.GenericForeignKey

Django model inheritance is a cool thing, and nice as a shortcut for making your models DRYer, but doesn't always play nicely with the polymorphic ideas we generally have of classes.

answered 2011-09-23T21:45:01.323

Your Answer