使用For循环与url方法时Django抛出NoReverseMatch错误的原因
问题:Django模板For循环中使用entry迭代器和url模板方法时触发NoReverseMatch错误
错误信息
NoReverseMatch at /
Reverse for 'entry' with keyword arguments '{'title': ''}' not found. 1 pattern(s) tried:['wiki/(?P[^/]+)\Z'] Line 12.
模板代码
{% extends "encyclopedia/layout.html" %} {% block title %} Encyclopedia {% endblock %} {% block body %} <h1>All Pages</h1> <ul> {% for entry in entries %} <li><a href="{% url 'entry' title=entry %}">{{ entry }}</a></li> {% comment %} <p> {{ entry }} </p> {% endcomment %} {% endfor %} </ul> {% comment %} <a href "/wiki/{{ entry }}"> <li>{{ entry }}</li> </a> {% endcomment %} {% endblock %}
补充说明
尝试在页面中打印带链接的条目列表,模板可正常输出列表元素,但使用url模板方法时页面无法渲染,触发上述错误。
urls.py代码
from django.urls import path from . import views urlpatterns = [ path("", views.index, name="index"), path("wiki/<str:title>", views.entry, name="entry"), path("search/", views.search, name="search"), path("new/", views.new_page, name="new_page"), path( "edit/", views.edit, name="edit"), path( "save_edit/", views.save_edit, name="save_edit"), path( "rand/", views.rand, name= "rand") ]
views.py代码
from django.shortcuts import render import markdown from . import util import random def convert_md_to_html(title): content = util.get_entry(title) markdowner = markdown.Markdown() if content == None: return None else: return markdowner.convert(content) def index(request): return render(request, "encyclopedia/index.html", { "entries": util.list_entries() }) def entry(request, title): html_content = convert_md_to_html(title) if html_content == None: return render(request, "encyclopedia/error.html",{ "message": "This entry does not exist" }) else: return render(request, "encyclopedia/entry.html",{ "title": title, "content": html_content }) def search(request): if request.method == "POST": entry_search = request.POST['q'] html_content = convert_md_to_html(entry_search) if html_content is not None: return render(request, "encyclopedia/entry.html",{ "title": entry_search, "content":html_content }) else: allEntries = util.list_entries() recommendation = [] for entry in allEntries: if entry_search.lower() in entry.lower(): recommendation.append(entry) return render(request, "encyclopedia/search.html", { "recommendation": recommendation }) def new_page(request): if request.method == "GET": return render(request, "encyclopedia/new.html") else: title = request.POST['title'] content = request.POST['content'] titleExist = util.get_entry(title) if titleExist is not None: return render(request, "encyclopedia/error.html", { "message": "Entry page already exist" }) else: util.save_entry(title, content) html_content = convert_md_to_html(title) return render(request, "encyclopedia/entry.html", { "title": title, "content": html_content }) def edit(request): if request.method == 'POST': title = request.POST['entry_title'] content = util.get_entry(title) return render(request, "encyclopedia/edit.html",{ "title": title, "content": content }) def save_edit(request): if request.method == "POST": title = request.POST['title'] content = request.POST['content'] util.save_entry(title, content) html_content = convert_md_to_html(title) return render(request, "encyclopedia/entry.html",{ "title": title, "content": html_content }) def rand(request): allEntries = util.list_entries() rand_entry = random.choice(allEntries) html_content = convert_md_to_html(rand_entry) return render(request, "encyclopedia/entry.html",{ "title" : rand_entry, "content" : html_content })
问题分析与解决方法
错误提示明确显示title参数为空字符串,说明util.list_entries()返回的列表中存在空元素,导致循环时entry为空,无法匹配wiki/<str:title>的路由规则(该规则要求title为非空字符串)。
解决步骤:
修复条目列表生成逻辑:检查
util.py中的list_entries函数,确保返回的列表过滤掉空字符串。例如:def list_entries(): # 原有读取文件逻辑 entries = [f[:-3] for f in os.listdir("entries") if f.endswith(".md")] # 过滤空条目 return [entry for entry in entries if entry.strip()]模板中添加空值过滤:在循环时跳过空的
entry,避免生成无效URL:{% for entry in entries %} {% if entry %} <li><a href="{% url 'entry' title=entry %}">{{ entry }}</a></li> {% endif %} {% endfor %}路由规则优化(可选):如果业务允许处理空标题(不推荐),可修改路由为
path("wiki/<str:title>/", views.entry, name="entry")并在视图中处理空标题场景,但更合理的做法是确保传入的title始终有效。
内容的提问来源于stack exchange,提问作者Angeluz
相关产品推荐
相关产品推荐

