我有这样的模特:
class Comment(models.Model):
text = models.TextField(max_length = 250, blank = False)
author = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
class Product(models.Model):
name = models.CharField(max_length = 40)
comments = generic.GenericRelation(Comment)
在此模板中,我显示了所有产品的最新5条评论:
<ul>
{% for comment in last_comments %}
<li><a href="/user/{{ comment.author }}/">{{ comment.author }}</a> on <a href="/product/{{ comment.content_object.name }}/">{{ comment.content_object }}</a>
<br>{{ comment.text }}</li>
{% endfor %}
</ul>
如果我last_comments
使用last_comments = Comment.objects.all().order_by('-id')[:5]
django调试工具栏,则表示执行了25次查询。
如果last_comments
使用last_comments = Comment.objects.select_related().all().order_by('-id')[:5]
django调试工具栏,则表示已执行了20次查询。
但为什么select_related
也没有选择相关的content_object呢?在django调试工具栏中,我看到5个获取产品的查询。肯定是{{ comment.content_object }}
原因可能是因为我在Comment
模型中使用 GenericForeignKey 。
你有什么想法吗?
答案 0 :(得分:-1)
您可以尝试重构数据库,使其看起来像这样:
class Comment(models.Model):
...
content_object = models.ForeignKey(Content)
class Content(models.Model):
text = models.CharField(max_length=123)
class SomeSpecificContent(models.Model):
...
content = models.ForeignKey(Content)
class OtherSpecificContent(models.Model):
...
content = models.ForeignKey(Content)
在Django的情况下实际上是一个非常类似的模式:
class Comment(models.Model):
...
content_object = models.ForeignKey(Content)
class Content(models.Model):
text = models.TextField()
class SomeSpecificContent(Content):
...
class OtherSpecificContent(Content):
...
因为这基本上是如何在Django中处理继承。后者可能不太灵活,如果SomeSpecificContent和OtherSpecificContent实际上代表完全不同的概念,可能有点难以理解。
另一方面,通用关系无法正确处理,因为它们可以链接到您想要的任何表。因此,如果您有可能发生的5个对象的列表,则每个对象都与不同类型的实体相关。不确定Django如何处理100个对象与5种类型的实体相关的情况。它实际上会生成5 + 1个查询吗?