You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django表单提交后如何修改视图URL去除用户名后缀?

Django博客评论提交后URL跳转问题解决方案

问题描述

在Django开发的博客项目中,单篇文章详情页URL为http://127.0.0.1:8002/articles/article/aviary-ensemble/(aviary-ensemble为文章slug),页面内置评论提交表单。当前details视图同时处理页面加载与评论创建逻辑,URL配置包含两条路径:一条带<str:author>参数,一条不带。提交评论后,URL自动变为带用户名后缀的地址(如http://127.0.0.1:8002/articles/article/aviary-ensemble/admin/),期望提交后回到无后缀的原详情页地址。尝试修改request.path_info未生效,寻求可行实现方案。

相关代码如下:

视图代码

def details(request, slug, author=None):
    article = models.Article.objects.get(slug=slug)
    print(author)
    if request.method == 'POST':
        if author is not None:
            user = User.objects.get(username=author)
            print(user.username, type(user))
            comment_author = UserProfile.objects.get(user=user)
            comment = request.POST['comment_area']
            if comment[0] == '@':
                receiver = comment[1:].split(', ')[0]
                comment_text = comment[1:].split(', ')[1]
                models.Comment.objects.create(article=article, author=comment_author, receiver=receiver, text=comment_text)
            else:
                models.Comment.objects.create(article=article, author=comment_author, text=comment)
            article_comments = models.Comment.objects.filter(article=article)
            context = {'article': article, 'article_comments': article_comments}
            return render(request, 'articles/article.html', context=context)
    else:
        article.views = article.views + 1
        article_comments = models.Comment.objects.filter(article=article)
        context = {'article': article, 'article_comments': article_comments}
        return render(request, 'articles/article.html', context=context)

URL配置

urlpatterns = [
    path('', views.index, name='articles_catalog'),
    path('article/<slug:slug>/<str:author>/', views.details, name='comment_creation'),
    path('article/<slug:slug>/', views.details, name='details'),
]

解决方案

核心问题分析

提交后URL带author后缀的原因是:表单提交到了带<str:author>参数的comment_creation路由,且处理完POST请求后直接用render返回页面,浏览器会保留当前请求的URL。修改request.path_info仅改变Django内部请求路径,不会触发浏览器地址栏更新。

方案一:POST处理后重定向到无author的详情页(快速修复)

遵循POST/REDIRECT/GET模式,处理完评论创建后,用redirect跳转到不带author参数的details路由,强制浏览器更新地址栏。

修改视图的POST分支代码:

if request.method == 'POST':
    if author is not None:
        # 保留原评论创建逻辑
        user = User.objects.get(username=author)
        comment_author = UserProfile.objects.get(user=user)
        comment = request.POST['comment_area']
        if comment[0] == '@':
            receiver = comment[1:].split(', ')[0]
            comment_text = comment[1:].split(', ')[1]
            models.Comment.objects.create(article=article, author=comment_author, receiver=receiver, text=comment_text)
        else:
            models.Comment.objects.create(article=article, author=comment_author, text=comment)
    # 替换原render语句,重定向到无author的详情页
    return redirect('details', slug=slug)

方案二:调整表单提交目标(避免依赖重定向)

直接修改模板中的评论表单,让它提交到不带author参数的details路由,同时通过隐藏字段传递author信息(如果需要)。

  1. 模板中修改表单提交地址:
<form method="post" action="{% url 'details' slug=article.slug %}">
    {% csrf_token %}
    <!-- 隐藏传递author参数 -->
    <input type="hidden" name="author" value="{{ request.user.username }}">
    <textarea name="comment_area"></textarea>
    <button type="submit">提交评论</button>
</form>
  1. 视图中从POST参数获取author,移除URL的author参数:
def details(request, slug):
    article = models.Article.objects.get(slug=slug)
    if request.method == 'POST':
        author_username = request.POST.get('author')
        if author_username:
            user = User.objects.get(username=author_username)
            comment_author = UserProfile.objects.get(user=user)
            comment = request.POST['comment_area']
            if comment[0] == '@':
                receiver = comment[1:].split(', ')[0]
                comment_text = comment[1:].split(', ')[1]
                models.Comment.objects.create(article=article, author=comment_author, receiver=receiver, text=comment_text)
            else:
                models.Comment.objects.create(article=article, author=comment_author, text=comment)
        return redirect('details', slug=slug)
    else:
        article.views += 1
        article.save()  # 原代码遗漏保存浏览量修改,需补充
        article_comments = models.Comment.objects.filter(article=article)
        context = {'article': article, 'article_comments': article_comments}
        return render(request, 'articles/article.html', context=context)

方案三:移除带author的URL路由(最佳实践)

无需通过URL传递用户信息,直接用request.user获取当前登录用户,简化路由配置,彻底避免URL混乱。

修改后的URL配置:

urlpatterns = [
    path('', views.index, name='articles_catalog'),
    path('article/<slug:slug>/', views.details, name='details'),
]

修改后的视图代码:

def details(request, slug):
    article = models.Article.objects.get(slug=slug)
    if request.method == 'POST':
        # 直接从当前登录用户获取信息(需确保用户已登录)
        if request.user.is_authenticated:
            comment_author = UserProfile.objects.get(user=request.user)
            comment = request.POST['comment_area']
            if comment[0] == '@':
                receiver = comment[1:].split(', ')[0]
                comment_text = comment[1:].split(', ')[1]
                models.Comment.objects.create(article=article, author=comment_author, receiver=receiver, text=comment_text)
            else:
                models.Comment.objects.create(article=article, author=comment_author, text=comment)
        return redirect('details', slug=slug)
    else:
        article.views += 1
        article.save()
        article_comments = models.Comment.objects.filter(article=article)
        context = {'article': article, 'article_comments': article_comments}
        return render(request, 'articles/article.html', context=context)

内容的提问来源于stack exchange,提问作者Ксения Манжула

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:33:14