我正在使用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 条评论相关查询来列出评论 + 用户 + 个人资料,因为...
-
如果
Comment.__unicode__
实际上会调用Comment.user
。 +1 查询get_profile
+1 查询
user_id
存在,哎呀!
我从约 25 毫秒内的 203 个查询减少到约 2 毫秒内的 3 个查询。
自行填充comment_list
我强烈建议使用适当的select_lated()
调用自己构建comment_list
QuerySet
。如果经常使用,请创建一个从其他 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
类需要 OneToOneField
到 User
,其 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/