Hi everyone! I have N+1 problem inside Django Admin when use Generic Relations. Here is a sample:
class Category(models.Model):
title = models.CharField()
notes = GenericRelation('Notes')
class Author(models.Model):
name = models.CharField()
notes = GenericRelation('Notes')
class Book(models.Model):
title = models.CharField()
author = models.ForeignKey(Author)
category = models.ForeignKey(Category)
notes = GenericRelation('Notes')
def __str__(self):
return f'{self.author.name} - {self.title} - {self.category.title}'
class Notes(models.Model):
text = models.TextField()
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
note_to = GenericForeignKey('content_type', 'object_id')
def __str__(self):
return f"Note for {self.note_to}: {self.text[:50]}"
So you can write note to any entity (except note to note). When I generate a list of notes in Django Admin, I receive N+1 problem due to Book string representation.
I know that I should use select_related/prefetch_related. And in the list of Books I can easily create custom query set and use it, for example:
class BookQuerySet(models.QuerySet):
def with_related(self):
return self.select_related('author', 'category')
class Book(models.Model):
....
objects = BookQuerySet.as_manager()
....
And then in book/admin.py:
def get_queryset(self, request):
return super().get_queryset(request).with_related()
But I don’t understand how to apply the same functionality to Generic Relations. Also, maybe in future Category string representation will have more complex structure with foreignkey (like Book now). And how to resolve this issue in common way?