Django通过AJAX向带参数调度URL传参及NoReverseMatch错误解决
问题原因
你遇到的NoReverseMatch报错核心原因是:你在urls.py中定义的get_category路由要求必须传入category路径参数,但是你在模板中调用{% url 'get_category' %}时没有传入任何参数,Django无法完成路由反向解析。
解决方案
有两种常用的修复方案,你可以根据自己的需求选择:
方案1:修改路由为无需路径参数
如果你希望把category放在AJAX请求参数里传递,不需要走路径参数,直接修改路由规则即可:
- 修改
urls.py:
urlpatterns=[ # 去掉路径中的<str:category>参数,保持路径为普通接口 path('category/', views.getcategory, name = 'get_category'), ]
- 同步修改视图函数的参数获取逻辑:
你的AJAX用的是POST方法,现在视图里只处理了GET请求的参数获取,而且取的字段名和你传的不匹配,调整为:
def get_category(request, category=None): # 兼容高版本Django废弃is_ajax的情况,也可以保留原有is_ajax判断 is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest' if is_ajax and request.method == "POST": # 从POST参数里取你传的category字段 category = request.POST.get("category", category) # 注意要加CSRF校验,你可以在AJAX请求头里加X-CSRFToken,或者给视图加@csrf_exempt装饰器(不推荐) if category!=None: return HttpResponse('\n Received via Json. \n') else: return HttpResponse('\n Received via URL. \n')
方案2:沿用现有路由规则,JS动态替换路径参数
如果你不想改现有路由结构,就需要在JS里动态拼接带参数的路由:
- 先在模板的JS部分定义一个带占位符的路由:
// 先渲染一个带占位符的路由,Django可以正常解析 const categoryBaseUrl = "{% url 'get_category' 'temp_placeholder' %}"; function send_category(category){ $.ajax({ type: 'POST', // 把占位符替换为实际的category值 url: categoryBaseUrl.replace('temp_placeholder', category), data: {'category':category}, // 记得加CSRF头,避免403报错 headers: {'X-CSRFToken': document.cookie.match(/csrftoken=([^;]+)/)[1]}, success: function(response) { console.log("\n\nCategory data Successfully recived.\n"); console.log( response ); }, error: function (response) { console.log('\n\n error in retriving category data:'); console.log(response); } }) }
其他注意点
- Django 3.1及以上版本已经移除了
request.is_ajax方法,建议自己通过X-Requested-With请求头判断是否为AJAX请求 - POST请求默认需要CSRF校验,要么在请求头里加
X-CSRFToken,要么调整请求方法为GET,避免出现403错误 - 你原来的视图里从GET参数取的是
last_joke_id,和AJAX传的category字段不匹配,要注意同步修改字段名
内容的提问来源于stack exchange,提问作者Aananda Giri
相关产品推荐
相关产品推荐

