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

点击评论按钮出现NoReverseMatch错误,求Django新手帮助

Django评论功能触发NoReverseMatch错误的解决方案

我之前点击点赞按钮时遇到过NoReverseMatch错误,已经解决了。但创建评论视图及相关内容后,点击评论按钮时这个错误再次出现。我是Django新手,求帮忙。

项目代码

models.py

from email.policy import default
from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Blog(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=200, verbose_name="Put a Title")
    blog_content = models.TextField(verbose_name="What is on your mind")
    blog_image = models.ImageField(upload_to="blog_images", default = "/default.png")
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

class Comment(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name = "blog_comment" )
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "user_comment")
    comment = models.TextField()
    comment_date = models.DateField(auto_now_add=True)

    def __str__(self):
        return self.comment

class Like(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name = "blog_liked")
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "user_liked")

class Unlike(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name = "blog_unliked")
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "user_unliked")

blog_page.html

{% extends "main.html" %}
{% load static %}
{% load crispy_forms_tags %}
{% block content %}

<div style="text-align:center;">
    <h2>{{blog.title}}</h2>
    <img src="{{blog.blog_image.url}}" alt="" width="630px" height="300px">
</div>
<div style="text-align:center;">
    {{blog.blog_content|linebreaks}}
</div>
{% if not liked and not unliked %}
<h4> <a href="{% url 'like' blog.pk %}">Like</a> </h4>
<h4><a href="{% url 'unlike' blog.pk %}">Unlike</a></h4>

{% elif unliked %}
<h4> <a href="{% url 'like' blog.pk %}">Like</a> </h4>
{% elif liked %}
<h4><a href="{% url 'unlike' blog.pk %}">Unlike</a></h4>
{% endif %}

<div>
    <h4>
        Comments:
    </h4>
    {% for comment in comments %}
    <div>
        {{ user }} <br>
        <h5>{{ comment }}</h5>
    </div>
    {% endfor %}
    <!-- <h6>Add your comment:</h6> -->
    <form action="" method="POST">
        {% csrf_token %}
        {{form|crispy}} <br>
        <a class="btn btn-sm btn-info" href="{% url 'comment' %}">Comment</a>
    </form>
</div>

{% endblock content %}

urls.py

from django.urls import path
from blog_app import views 

urlpatterns = [
    path("", views.home, name='home'),
    path("blog_page/<str:pk>/", views.blog_view, name='blog_page'),
    path("like/<str:pk>/", views.like, name="like"),
    path("unlike/<str:pk>/", views.unlike, name="unlike"),
    path("comment/", views.comment, name="comment"),
]

views.py

from django.shortcuts import render
from . models import Blog, Comment, Like, Unlike
from . forms import CommentForm

# Create your views here.
def home(request):
    blogs = Blog.objects.all()
    context = {'blogs': blogs}
    return render(request, 'blog_app/home.html', context)

def blog_view(request, pk):
    blog = Blog.objects.get(id=pk)
    form = CommentForm()
    comments = Comment.objects.filter(blog=blog)
    context = {"blog": blog, "comments": comments, "form":form}
    return render(request, 'blog_app/blog_page.html', context)
    
def like(request, pk):
    blog = Blog.objects.get(id=pk)
    user = request.user
    liked, like = Like.objects.get_or_create(blog=blog, user=user)
    context = {"liked" : liked, "blog": blog }
    return render(request, "blog_app/blog_page.html", context)

def unlike(request, pk):
    blog = Blog.objects.get(id=pk)
    user = request.user
    unliked, unlike = Unlike.objects.get_or_create(blog=blog, user=user)
    context = {"unliked" : unliked, 'blog': blog}
    return render(request, "blog_app/blog_page.html", context)

def comment(request):
    form = CommentForm()
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            form.save()
    context = {}
    return render(request, "blog_app/blog_page.html", context)

错误原因分析

  1. 评论按钮用<a>标签跳转,属于GET请求,无法提交表单数据,且当前评论URL未携带博客ID参数,触发反向解析错误。
  2. 评论视图未接收博客ID,无法将评论关联到对应博客;直接form.save()会缺失必填的blog和user字段。
  3. 表单action为空,按钮用链接跳转导致表单未被正确提交。

解决方案

1. 修改urls.py,给评论URL添加博客ID参数

urlpatterns = [
    # ... 其他URL不变
    path("comment/<str:pk>/", views.comment, name="comment"),
]

2. 修改blog_page.html的表单提交逻辑

将评论按钮改为<button>,用POST提交,并指定带博客ID的表单action:

<form action="{% url 'comment' blog.pk %}" method="POST">
    {% csrf_token %}
    {{form|crispy}} <br>
    <button class="btn btn-sm btn-info" type="submit">Comment</button>
</form>

3. 修改views.py的comment视图

接收博客ID参数,关联评论到对应博客和当前用户,并重定向避免重复提交:

from django.shortcuts import render, redirect

# ... 其他视图不变
def comment(request, pk):
    blog = Blog.objects.get(id=pk)
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.blog = blog
            comment.user = request.user
            comment.save()
            return redirect('blog_page', pk=pk)
    else:
        form = CommentForm()
    comments = Comment.objects.filter(blog=blog)
    context = {"blog": blog, "comments": comments, "form": form}
    return render(request, "blog_app/blog_page.html", context)

4. 完善CommentForm表单(若未配置)

确保表单只显示用户需要输入的字段,排除后台自动赋值的字段:

# forms.py
from django import forms
from .models import Comment

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ['comment']  # 仅显示评论内容输入框

额外优化:修复点赞/点踩视图的页面渲染问题

将点赞/点踩视图改为重定向回博客详情页,同时在博客详情视图中判断用户是否已点赞/点踩:

# views.py
def like(request, pk):
    blog = Blog.objects.get(id=pk)
    user = request.user
    Like.objects.get_or_create(blog=blog, user=user)
    return redirect('blog_page', pk=pk)

def unlike(request, pk):
    blog = Blog.objects.get(id=pk)
    user = request.user
    Unlike.objects.get_or_create(blog=blog, user=user)
    return redirect('blog_page', pk=pk)

def blog_view(request, pk):
    blog = Blog.objects.get(id=pk)
    form = CommentForm()
    comments = Comment.objects.filter(blog=blog)
    # 判断当前用户的点赞/点踩状态
    liked = Like.objects.filter(blog=blog, user=request.user).exists()
    unliked = Unlike.objects.filter(blog=blog, user=request.user).exists()
    context = {"blog": blog, "comments": comments, "form": form, "liked": liked, "unliked": unliked}
    return render(request, 'blog_app/blog_page.html', context)

内容的提问来源于stack exchange,提问作者Shishir Rehan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:06:00