繁体   English   中英

Django select_related() 和 GenericForeignKey

[英]Django select_related() and GenericForeignKey

我有这样的模型:

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 得到 last_comments 调试工具栏说执行了 25 个查询。

如果我用last_comments last_comments = Comment.objects.select_related().all().order_by('-id')[:5] django 得到 last_comments 调试工具栏说执行了 20 个查询。

但是为什么select_related select 也没有相关的 content_object 呢? 在 django 调试工具栏中,我看到 5 个获取产品的查询。 并且肯定是{{ comment.content_object }}的结果

可能是因为我在Comment model 中使用了GenericForeignKey

你有想法吗?

您可以尝试重构您的数据库,使其看起来像这样:

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 个查询吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM