点击评论按钮出现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)
错误原因分析
- 评论按钮用
<a>标签跳转,属于GET请求,无法提交表单数据,且当前评论URL未携带博客ID参数,触发反向解析错误。 - 评论视图未接收博客ID,无法将评论关联到对应博客;直接
form.save()会缺失必填的blog和user字段。 - 表单
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
相关产品推荐
相关产品推荐

