为URL添加主键后出现NoReverseMatch错误的排查求助
Django添加pk后出现NoReverseMatch错误的解决方案
我是编程新手,在Django项目的urls模块中为URL地址添加主键(pk)后出现了NoReverseMatch错误。以下是项目相关代码文件:
原项目代码文件
settings.py
from pathlib import Path import os BASE_DIR = Path(__file__).resolve().parent.parent TEMPLATES_DIR=os.path.join(BASE_DIR,"templates") SECRET_KEY = 'django-insecure-6mtsgnhk=-=5ka0-e4619v0_uq)s+t=dtybe8^ojwmg1gwoj**' DEBUG = True ALLOWED_HOSTS = [] INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'g7app', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'g7.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [TEMPLATES_DIR,], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'g7.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
urls.py
from django.contrib import admin from django.urls import path from g7app.views import CreatePost,View1,View2,EditPost,DeleteView,CreatePost urlpatterns = [ path('admin/', admin.site.urls), path("",View1.as_view(),name="home"), path("post/<int:pk>/",View2.as_view(),name="post_detail"), path("post/<int:pk>/post_edit/",EditPost.as_view(),name="post_edit"), path("post/<int:pk>/post_delete/",DeleteView.as_view(),name="post_delete"), path("post/new/",CreatePost.as_view(),name="post_new"), ]
admin.py
from django.contrib import admin from .models import Student admin.site.register(Student)
models.py
from django.db import models from django.urls import reverse class Student(models.Model): name=models.CharField(max_length=100) description=models.CharField(max_length=100) def __str__(self): return self.name def get_absolute_url(self): return reverse("post_detail", args=[self.pk])
views.py
from django.shortcuts import render from django.views.generic import ListView, DetailView from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.urls import reverse_lazy from .models import Student class View1(ListView): context_object_name="con1" template_name="home.html" model=Student class View2(DetailView): context_object_name="con2" template_name="post_detail.html" model=Student class CreatePost(CreateView): fields=["name","description"] template_name="create_post.html" model=Student class EditPost(UpdateView): fields=["description"] template_name="edit_post.html" model=Student class DeleteView(DeleteView): template_name="delete_post.html" model=Student success_url=reverse_lazy("home")
base.html
<!DOCTYPE HTML> <HTML> <head> <meta charset="utf-8"> <title></title> </head> <body> <h1>Blog Application</h1> {% block c1 %} <h2><a href="{% url 'post_new' %}">+Create_Post</a></h2> {% endblock c1 %} </body> </HTML>
home.html
{% extends "base.html" %} {% block c1 %} {% for Student in con1 %} <h2><a href="{% url 'post_detail' Student.pk %}">{{Student.name}}</a></h2> <h4>{{Student.description}}</h4> {% endfor %} {% endblock c1 %}
post_detail.html
{% extends "base.html" %} {% block c1 %} <div> <h2>{{con2.name}}</h2> <h4>{{con2.description}}</h4> </div> <p><a href="{% url 'post_edit' Student.pk %}">Edit post</a></p> <p><a href="{% url 'post_delete' Student.pk %}">Delete post</a></p> {% endblock c1 %}
create_post.html
<!DOCTYPE HTML> <HTML> <head> <meta charset="utf-8"> <title></title> </head> <body> {% extends "base.html" %} {% block c1 %} <form method="post"> {csrf_token} {{form.as_p}} <input type="submit" value="save"> </form> {% endblock c1 %} </body> </HTML>
edit_post.html
{% extends "base.html" %} {% block c1 %} <div> <h3>edit information</h3> <form method="post"> {csrf_token} {{form.as_p}} <input type="submit" value="save"> </form> </div> {% endblock c1 %}
delete_post.html
{% extends "base.html" %} {% block c1 %} <div> <h3>delet post</h3> <form method="post"> {csrf_token} {{form.as_p}} <input type="submit" value="save"> </form> </div> {% endblock c1 %}
错误原因分析
- 模板变量引用错误:
post_detail.html中,DetailView指定了context_object_name="con2",但模板里错误地使用了Student.pk,模板上下文中不存在名为Student的变量,导致无法生成正确的URL。 - CSRF标签语法错误:多个模板中的
{csrf_token}缺少百分号,正确写法应为{% csrf_token %},否则Django无法识别该标签。 - 视图类名冲突:
views.py中自定义的DeleteView与导入的django.views.generic.edit.DeleteView重名,导致视图无法正常加载。 - 拼写错误:
delete_post.html中的标题"delet post"应为"delete post"。
修复后的代码
1. post_detail.html(修正变量引用)
{% extends "base.html" %} {% block c1 %} <div> <h2>{{con2.name}}</h2> <h4>{{con2.description}}</h4> </div> <p><a href="{% url 'post_edit' con2.pk %}">Edit post</a></p> <p><a href="{% url 'post_delete' con2.pk %}">Delete post</a></p> {% endblock c1 %}
2. views.py(修改DeleteView类名避免冲突)
from django.shortcuts import render from django.views.generic import ListView, DetailView from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.urls import reverse_lazy from .models import Student class View1(ListView): context_object_name="con1" template_name="home.html" model=Student class View2(DetailView): context_object_name="con2" template_name="post_detail.html" model=Student class CreatePost(CreateView): fields=["name","description"] template_name="create_post.html" model=Student class EditPost(UpdateView): fields=["description"] template_name="edit_post.html" model=Student # 重命名类名,避免与导入的DeleteView冲突 class StudentDeleteView(DeleteView): template_name="delete_post.html" model=Student success_url=reverse_lazy("home")
3. urls.py(更新DeleteView的引用)
from django.contrib import admin from django.urls import path from g7app.views import CreatePost, View1, View2, EditPost, StudentDeleteView urlpatterns = [ path('admin/', admin.site.urls), path("", View1.as_view(), name="home"), path("post/<int:pk>/", View2.as_view(), name="post_detail"), path("post/<int:pk>/post_edit/", EditPost.as_view(), name="post_edit"), path("post/<int:pk>/post_delete/", StudentDeleteView.as_view(), name="post_delete"), path("post/new/", CreatePost.as_view(), name="post_new"), ]
4. create_post.html(修正CSRF标签)
{% extends "base.html" %} {% block c1 %} <form method="post"> {% csrf_token %} {{form.as_p}} <input type="submit" value="save"> </form> {% endblock c1 %}
5. edit_post.html(修正CSRF标签)
{% extends "base.html" %} {% block c1 %} <div> <h3>edit information</h3> <form method="post"> {% csrf_token %} {{form.as_p}} <input type="submit" value="save"> </form> </div> {% endblock c1 %}
6. delete_post.html(修正拼写和CSRF标签)
{% extends "base.html" %} {% block c1 %} <div> <h3>delete post</h3> <form method="post"> {% csrf_token %} {{form.as_p}} <input type="submit" value="save"> </form> </div> {% endblock c1 %}
内容的提问来源于stack exchange,提问作者Dhani
相关产品推荐
相关产品推荐

