django - 如何使 Django 注释在 "user"字段上使用 select_lated() ?

标签 django performance

我正在使用django comments frameworks 。所有评论均由经过身份验证的用户发布。在评论附近,我使用 {{ comment.user.get_profile }}

显示一些用户个人资料信息
{# custom comment list templates #}
<dl id="comments">
  {% for comment in comment_list %}
    <dt id="c{{ comment.id }}">
        {{ comment.submit_date }} - {{ comment.user.get_profile.display_name }}
    </dt>
    <dd>
        <p>{{ comment.comment }}</p>
    </dd>
  {% endfor %}
</dl>

问题是 django 的评论查询不使用 select_lated(),对于 100 条评论,我在数据库上得到了 101 次点击。

有没有一种方法可以让 django 评论框架一次性为每个评论选择用户个人资料?

最佳答案

我测试了使用默认 {% get_comment_list %} 标记为对象呈现 100 条评论,django 执行了 200 条评论相关查询来列出评论 + 用户 + 个人资料,因为...

    如果 user_id 存在,
  1. Comment.__unicode__ 实际上会调用 Comment.user。 +1 查询
  2. get_profile +1 查询

哎呀!

我从约 25 毫秒内的 203 个查询减少到约 2 毫秒内的 3 个查询。

自行填充comment_list

强烈建议使用适当的select_lated()调用自己构建comment_listQuerySet。如果经常使用,请创建一个从其他 View 调用的实用函数。

def get_comments_with_user_and_profile(obj):
    content_type =ContentType.objects.get_for_model(obj)
    return (Comment.objects
        .filter(content_type=content_type, object_pk=obj.id)
        .select_related('user__profile'))

如果您希望整个框架以这种方式运行...您必须进行猴子修补。

这不是我会轻易做的事情。还有其他方法可以解决这个特定问题,但您确实“一口气”问了。

将其放在 INSTALLED_APPS models.py 文件中的某个位置。我实际上有一个 monkey_patch 应用程序,用于修改 django.contrib.auth.User.username 长度等(这是与这里不同的最后手段)。

from django.contrib.comments.models import Comment
from django.contrib.comments.managers import CommentManager

class CommentManager(CommentManager):
    def get_query_set(self):
        return (super(CommentManager, self)
            .get_query_set()
            .select_related('user__profile'))
Comment.add_to_class('objects', CommentManager())

配置文件和 select_lated() 的陷阱

请注意,您的 UserProfile 类需要 OneToOneFieldUser,其 lated_name 等于您传递给的内容select_lated()。在我的示例中,它是 profile 并且您需要 django 1.2+。我记得以前偶然发现过这一点。

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='profile') 
    # example to use User.objects.select_related('profile')

关于django - 如何使 Django 注释在 "user"字段上使用 select_lated() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7887141/

相关文章:

javascript - 哪个for循环在javascript中更有效?

python - Django,SQLite - 带重音字母的字符串的准确排序

django - Django和Flask是否需要单独的Web服务器来运行Web应用程序?

python - Mavericks 上的 Django 和 mysql 问题

Django 获取用户创建的对象,这些用户属于用户列表

javascript - JQuery 每个循环的延迟不适用于发布请求

javascript - 对现有 jQuery 对象进行 jQuery 处理是否有成本?

objective-c - 使用 respondsToSelector 的性能损失

python - 在 Django 模板中访问带有前导下划线的字典元素

c++ - 使用指针缓慢迭代字符串