Django中Reverse for 'design'参数为空报错求助
错误信息
NoReverseMatch at /builder/
Reverse for 'design' with arguments '('', '')' not found. 1 pattern(s) tried:
['builder\/design\/(?P<template_id>[/]+)\/(?P<template_type>[/]+)\/$']
我正在开发一款供用户选择布局的模板构建器,遇到上述错误。已尝试同类问题的解决方案,检查过变量名、模板及上下文数据,但问题未解决。以下是相关代码:
视图函数
from django.contrib.auth.decorators import login_required from django.db.models import Q from django.shortcuts import render def index(request): user_id = request.user.id templates = Template.objects.filter(Q(user_id=user_id) | Q(user_id=1), builder=2).order_by('id') layouts = templates.filter(layout=1, user_id=1).order_by('title') others = templates.filter(layout=2, user_id=1).order_by('id') owns = templates.filter(user_id=user_id).order_by('id') context = {'title': 'Template Builder', 'layouts': layouts, 'others': others, 'owns': owns} return render(request, 'builder/index.html', context) @login_required(login_url='signin') def design(request, template_id, template_type): user_id = request.user.id path = MEDIA_ROOT + '/builderjs/' + str(user_id) + '/tmp/' create_builder_directory(path) json_template_data = get_template_data(user_id) if 'new_builder_create' not in request.session: request.session['new_builder_create'] = {template_id: 1} saving_builder_content_to_temporary(user_id, None) else: visit = request.session['new_builder_create'] if template_id not in visit.keys(): visit[template_id] = 1 else: visit[template_id] = visit[template_id] + 1 request.session['new_builder_create'] = visit print(request.session['new_builder_create']) context = {'title': 'Template Builder', 'template_id': template_id, 'template_type': template_type, 'json_template_data': json_template_data} return render(request, 'builder/design.html', context)
urls.py
from django.urls import path, re_path from . import views urlpatterns = [ path('', views.index, name='builder'), path('design/<str:template_id>/<str:template_type>/', views.design, name='design'), ]
模板代码(index.html)
<div class="card-body"> <div class="row"> {% for layout in layouts %} <div class="col-md-6 col-lg-4 col-xl-3 mb-30"> <div class="card"> <a target="_blank" type="button" href="{% url 'design' layout.id 'layouts' %}"> {{ layout.icon|safe }} </a> <div class="p-15"> <a target="_blank" type="button" href="{% url 'design' layout.id 'layouts' %}" class="btn btn-outline btn-block btn-warning">{{ layout.title }}</a> </div> </div> </div> {% endfor %} </div> </div> </div> <div class="card roundangel mb-30"> <div id="others" class="card-header"> <h4 class="card-title"> <span class="icon icon-sm"><i class="fs-20 fw-500 fa fa-filter"></i></span> <strong>Preset </strong>Templates </h4> </div> <div class="card-body"> <div class="row"> {% for layout in others %} <div class="col-md-6 col-lg-4 col-xl-3 mb-30"> <div class="card"> <a target="_blank" type="button" href="{% url 'design' layout.id 'other' %}"> <img width="100%" height="100%" class="_1xvs1" src="/media/builderjs/1/templates/{{ layout.id }}/thumb.png" title="{{ layout.title }}" alt="{{ layout.title }}"> </a> <div class="p-15"> <a target="_blank" type="button" href="{% url 'design' layout.id 'other' %}" class="btn btn-outline btn-block btn-warning">{{ layout.title }}</a> </div> </div> </div> {% endfor %} </div> </div> </div> <div class="card roundangel mb-30"> <div id="owns" class="card-header"> <h4 class="card-title"> <span class="icon icon-sm"><i class="fs-20 fw-500 fa fa-filter"></i></span> <strong>Your Own </strong>Templates </h4> </div> <div class="card-body"> <div class="row"> {% for layout in owns %} <div class="col-md-6 col-lg-4 col-xl-3 mb-30"> <div class="card"> <a target="_blank" type="button" href="{% url 'design' layout.id 'other' %}"> {% check_thumb_exist_tag layout.user_id layout.id as thumb %} {% if thumb %} <img width="100%" height="100%" class="_1xvs1 own-thumb" src="{{ thumb }}" title="{{ layout.title }}" alt="{{ layout.title }}"> {% else %} <img width="100%" height="100%" class="_1xvs1" src="{% static 'assets/vendor/builderjs/assets/image/default_thumb.png' %}" title="{{ layout.title }}" alt="{{ layout.title }}"> {% endif %} </a> <div class="p-15"> <a target="_blank" type="button" href="{% url 'design' layout.id 'other' %}" class="btn btn-outline btn-block btn-warning">{{ layout.title }}</a> </div> </div> </div> {% endfor %} </div> </div> </div>
问题排查与解决
错误提示显示调用design路由时传入了空参数('', ''),核心原因是模板中某个{% url 'design' %}调用未获取到有效的layout.id,或循环的QuerySet中存在无id的对象。
检查数据库数据完整性
在index视图中添加打印语句,确认返回的QuerySet中每个对象都有有效id:print("Layouts数据:", list(layouts.values('id', 'title'))) print("Others数据:", list(others.values('id', 'title'))) print("Owns数据:", list(owns.values('id', 'title')))若输出中存在
id为空的对象,需清理数据库中无效的Template记录,确保所有对象都有主键值。模板中增加空值过滤
在循环中添加判断,跳过无id的对象,避免生成无效的URL:{% for layout in layouts %} {% if layout.id %} <!-- 原卡片代码 --> {% endif %} {% endfor %}对
others和owns的循环做同样处理。排查自定义标签影响
临时注释owns循环中的{% check_thumb_exist_tag %}标签,测试是否仍报错,确认该标签是否修改了layout对象的属性导致id为空。确认路由参数兼容性
路由中使用<str:template_id>,Django会自动将整数类型的layout.id转为字符串,此部分无需修改,但需确保layout.id不为None。
内容的提问来源于stack exchange,提问作者afsana mimi

