Abstract patterns and foreign keys in Django

I am working on a django project in which I create a set of three abstract models that I will use for various applications later. The problem I am facing is that I want to connect these models via ForeignKey, but django tells me that it cannot assign additional keys to the abstract model.

My current solution is to assign extra keys when I run the class in other applications. However, I am writing a Manager for abstract classes (books and pages) right now and must access these additional keys. What I'm basically trying to do is get the number of words that the book has statelessness, so without saving them in the page or book box.

The model looks something like 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 

Please note that this model is just here to give an example of what I'm trying to do, so is this model (Book-Page-Word) not necessary from the point of view of implementation.

+7
source share
3 answers

Maybe you need a GenericForeignKey , since you really don't know which model your ForeignKey will indicate? This means that you will lose some “type security guarantees” of the normal relationship, but it will allow you to specify these relationships in a more general way. See https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#django.contrib.contenttypes.generic.GenericForeignKey

Inheriting a Django model is a cool thing, and it’s good as a shortcut to creating your DRYer models, but it doesn’t always go well with the polymorphic ideas that we usually have in classes.

+12
source

How about this approach? I myself plan to use it to delay the determination of relationships until I inherit it.

# This is a very contrived (but simple) example.

 def AbstractBook(AuthorModel): class AbstractBookClass(Model): name = CharField(max_length=10) author = ForeignKey(AuthorModel) class Meta: abstract = True return AbstractBookClass class AbstractAuthor(Model): name = CharField(max_length=10) class Meta: abstract = True class BadAuthor(AbstractAuthor): pass class BadBook(AbstractBook(BadAuthor)): pass class GoodAuthor(AbstractAuthor): pass class GoodBook(AbstractBook(GoodAuthor)): pass 
+4
source

Two things:

1) As you built your circuit, you will need a GenericForeignKey, as already mentioned. But you must keep in mind that a book through a page has a lot to do with Word, and GenericForeignKey just implements one-to-many . For a normalized scheme, Django still has nothing. What you need to do (if you want to normalize) is to implement the intermediate (with "pass-through" for specific models).

2) If you need language processing, using a relational database (with or without Django ORM) is not a very efficient approach, given the resulting database size and query time after dozens of books. Add to that the extra columns that you will need to find your joins due to abstract models, and this will soon become very impractical. I think that it would be more useful to study other approaches, for example, store only aggregates and / or denormalize (even in this case, look at non-relational storage systems) based on your requests and views.

0
source

All Articles