Django 线程评论和投票
我在项目中使用 django-threadedcomments 和 django-voting 来实现类似 Reddit 的评论投票系统。
我已经正确设置了所有内容,并且能够成功记录每个线程评论及其子评论的投票,但是我对如何对评论进行排序以使得分最高的评论上升到顶部感到有点困惑。
通过模板标签是一个解决方案吗?我尝试过这样做并返回了一个列表,其中的项目按 score
降序排序,但是评论的父子关系变得混乱。这就是我所做的:
class OrderByVotesNode(template.Node):
def __init__(self, queryset_var, direction="desc"):
self.queryset_var = template.Variable(queryset_var)
self.direction = direction
def render(self, context):
key = self.queryset_var.var
value = self.queryset_var.resolve(context)
try:
direction = template.Variable(self.direction).resolve(context)
except template.VariableDoesNotExist:
direction = "desc"
model = value.model
qn = connection.ops.quote_name
ctype = ContentType.objects.get_for_model(model)
by_score = model.objects.filter(id__in=[f.id for f in value]).extra(select={"score": """
SELECT coalesce(SUM(vote), 0 )
FROM %s
WHERE content_type_id = %s
AND object_id = %s.%s
""" % (qn(Vote._meta.db_table), ctype.id, qn(model._meta.db_table), qn(model._meta.pk.attname))},
order_by=[(direction == "desc" and "-" or "") + "score"])
context[key] = by_score
return u""
对此的任何帮助或建议将不胜感激。谢谢!
I'm using django-threadedcomments and django-voting in my project to achieve a Reddit-like comments voting system.
I've set everything up correctly and I'm able to successfully record votes for each threaded comment and its children, however I'm a bit stuck as to how to sort the comments so that the comment with the highest score rises to the top.
Would passing through a template tag be a solution? I've attempted this and returned a list where the items were ordered by score
descending, however the parent-child relationship of the comments got messed up. Here is what I did:
class OrderByVotesNode(template.Node):
def __init__(self, queryset_var, direction="desc"):
self.queryset_var = template.Variable(queryset_var)
self.direction = direction
def render(self, context):
key = self.queryset_var.var
value = self.queryset_var.resolve(context)
try:
direction = template.Variable(self.direction).resolve(context)
except template.VariableDoesNotExist:
direction = "desc"
model = value.model
qn = connection.ops.quote_name
ctype = ContentType.objects.get_for_model(model)
by_score = model.objects.filter(id__in=[f.id for f in value]).extra(select={"score": """
SELECT coalesce(SUM(vote), 0 )
FROM %s
WHERE content_type_id = %s
AND object_id = %s.%s
""" % (qn(Vote._meta.db_table), ctype.id, qn(model._meta.db_table), qn(model._meta.pk.attname))},
order_by=[(direction == "desc" and "-" or "") + "score"])
context[key] = by_score
return u""
Any help or suggestions on this would be greatly appreciated. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有两种策略:
1) 您只想对每个线程的最上面的评论进行排序。对查询添加一个限制,即该评论没有父评论(我不确定 threadedcomments 模型是如何设计的)。
2)您获取排序结果,并将每个评论遍历到其根父级。然后,从上到下过滤掉重复项。这样,每个线程都会根据线程中任何评论的最高分数进行评分。这更难实现,而且坦率地说,这在我看来并不是最直观的命令。
完成此操作后,您将获得一个有序的注释列表,您可以在模板中以线程方式显示这些注释(我假设您正在进行一些模板递归)。
There are two strategies:
1) You want to sort only on the topmost comment on every thread. Add a restriction on the query that this comment has no parent comment (I'm not sure how threadedcomments model is designed exactly).
2) You take the ordered result, and traverse every comment to its root parent. Then, you filter out duplicates from the top to the bottom. This way, each thread is scored according to the maximum score of any comment in the thread. This is harder to implement, and frankly, doesn't seem like the most intuitive order in my mind.
After you've done this, you have an ordered list of comments that you display in a threaded fashion in the template (I assume you have some template recursion going on).