我有一个数据结构,其中 aDocument
有很多Blocks
只有一个Paragraph
或Header
. 一个简化的实现:
class Document(models.Model):
title = models.CharField()
class Block(models.Model):
document = models.ForeignKey(to=Document)
content_block_type = models.ForeignKey(to=ContentType)
content_block_id = models.CharField()
content_block = GenericForeignKey(
ct_field="content_block_type",
fk_field="content_block_id",
)
class Paragraph(models.Model):
text = models.TextField()
class Header(models.Model):
text = models.TextField()
level = models.SmallPositiveIntegerField()
(请注意,与上面的实现不同,实际上需要在单独的模型中使用Paragraph
和。)Header
我使用jinja2
模板来为文档创建一个 Latex 文件。尽管 jinja 为每个块和段落或标题执行新的数据库查询,但模板化很慢。
template = get_template(template_name="latex_templates/document.tex", using="tex")
return template.render(context={'script': self.script})
\documentclass[a4paper,10pt]{report}
\begin{document}
{% for block in chapter.block_set.all() %}
{% if block.content_block_type.name == 'header' %}
\section{ {{- block.content_block.latex_text -}} }
{% elif block.content_block_type.name == 'paragraph' %}
{{ block.content_block.latex_text }}
{% endif %}
{% endfor %}
\end{document}
(content_block.latex_text()
是将 HTML 字符串转换为 Latex 字符串的函数)
因此我想预取script.blocks
和blocks.content_block
. 我知道在 Django 中有两种预取方法:
select_related()
执行JOIN
查询,但仅适用于ForeignKeys
. 它适用于script.blocks
但不适用于blocks.content_block
.prefetch_related()
也可与 GenericForeignKeys 一起使用,但如果我正确理解文档,它一次只能获取一个ContentType
,而我有两个。
有什么方法可以在这里执行必要的预取吗?谢谢您的帮助。