У меня есть нижеприведенная структура, где модули контента, которые разделены на подклассы из общей модели, прикрепляются к страницам с помощью модели «модуль страницы», которая ссылается на них через GenericForeignKey
:
class SitePage(models.Model):
title = models.CharField()
# [etc..]
class PageModule(models.Model):
page = models.ForeignKey(SitePage, db_index=True, on_delete=models.CASCADE)
module_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
module_id = models.PositiveIntegerField()
module_object = GenericForeignKey("module_type", "module_id")
class CommonModule(models.Model):
published_time = models.DateTimeField()
class SingleImage(CommonModule):
title = models.CharField()
# [etc..]
class Article(CommonModule):
title = models.CharField()
# [etc..]
На данный момент заполнение страниц из этого приводит к большому количеству SQL запросов. Я хочу извлечь все содержимое модуля (то есть все экземпляры SingleImage и Article) для данной страницы наиболее эффективным способом работы с базой данных.
Я не могу просто сделать прямое prefetch_related
, потому что оно "должно быть ограничено однородным набором результатов" , и я выбираю несколько типов контента.
Я могу получить каждый тип модуля индивидуально:
image_modules = PageModule.objects.filter(page=whatever_page, module_type=ContentType.objects.get_for_model(SingleImage)).prefetch_related('module_object_')
article_modules = PageModule.objects.filter(page=whatever_page, module_type=ContentType.objects.get_for_model(Article)).prefetch_related('module_object')
all_modules = image_modules | article_modules
Но я нужно отсортировать их:
all_modules.order_by('module_object__published_time')
и я не могу, потому что:
"Поле 'module_object' не генерирует автоматическое c обратное отношение и поэтому не может использоваться для обратных запросов "
... и я не думаю, что смогу добавить рекомендованное поле GenericRelation
ко всем моделям контента, потому что там уже есть контент.
Так ... я могу сделать это вообще? Или я застрял?