在Django反向函数中添加动态URL,实现评论锚点跳转
问题描述
我正在开发一个博客应用,提交评论或评论回复后,页面会跳转到文章页面顶部,我希望页面能直接跳转到刚发布的评论/回复位置(即滚动至对应锚点)。例如,提交后希望跳转至链接:http://127.0.0.1:8000/post/first#comment-12。
我尝试通过如下代码实现,但没有成功:
return HttpResponseRedirect(reverse(f'post_page#comment-{str(comment.id)}', kwargs={ 'slug': slug }))
当前我的views.py代码如下:
if request.POST: comment_form = CommentForm(request.POST) if comment_form.is_valid: if request.POST.get('parent'): parent_id = request.POST.get('parent') parent = Comments.objects.get(id=parent_id) if parent: comment_reply = comment_form.save(commit=False) comment_reply.parent = parent comment_reply.post = post comment_reply.save() else: comment = comment_form.save(commit=False) post_id = request.POST.get('post_id') post = Post.objects.get(id=post_id) comment.post = post comment.save() return HttpResponseRedirect(reverse('post_page', kwargs={ 'slug': slug }))
urls.py代码如下:
urlpatterns = [ path('', views.index, name='index'), path('post/<slug:slug>', views.post_page, name='post_page') ]
请问如何正确实现带动态锚点的URL跳转?
解决方案
Django的reverse函数仅负责生成路由部分的URL,不处理锚点(#之后的片段),所以需要先反转得到基础URL,再手动拼接锚点部分。
1. 统一获取评论/回复的ID
不管是新增评论还是回复,都要拿到最终生成的评论ID(回复本质也是带父级的评论),修改views.py逻辑,将新生成的评论实例存入变量:
if request.POST: comment_form = CommentForm(request.POST) # 注意:is_valid是方法,必须加括号调用 if comment_form.is_valid(): new_comment = None if request.POST.get('parent'): parent_id = request.POST.get('parent') parent = Comments.objects.get(id=parent_id) if parent: comment_reply = comment_form.save(commit=False) comment_reply.parent = parent comment_reply.post = post comment_reply.save() new_comment = comment_reply else: comment = comment_form.save(commit=False) post_id = request.POST.get('post_id') post = Post.objects.get(id=post_id) comment.post = post comment.save() new_comment = comment # 拼接基础URL与锚点 base_url = reverse('post_page', kwargs={'slug': slug}) redirect_url = f"{base_url}#comment-{new_comment.id}" return HttpResponseRedirect(redirect_url)
2. 模板中添加对应锚点ID
在渲染评论的模板里,每条评论(包括回复)的容器标签必须设置匹配的id属性,例如:
<div id="comment-{{ comment.id }}" class="comment-container"> <!-- 评论内容、回复按钮等 --> </div>
额外注意
- 原代码中
comment_form.is_valid漏写了括号,这会导致表单验证逻辑失效,必须修正为comment_form.is_valid()。 - 也可以使用Django的
redirect快捷函数简化写法:return redirect(f"{reverse('post_page', kwargs={'slug': slug})}#comment-{new_comment.id}")
内容的提问来源于stack exchange,提问作者A-Makeyev
相关产品推荐
相关产品推荐

