Django开发中无法获取URL传递的user_type参数问题求助
问题原因排查
- urls.py配置错误
- 路由顺序异常:无参数的
signUp路由写在带参数的路由之前,且没有加结束符$,所有/signUp开头的请求都会优先匹配第一个无参数路由,不会进入带u_type参数的路由,导致视图的u_type参数始终为空 - 带参数的路由正则规则错误:
(?P<u_type>)没有定义匹配规则,无法捕获参数值 - 所有路由都未加结束符
$,会出现路由匹配混乱问题,比如login路由会匹配所有带login字符的路径
- 路由顺序异常:无参数的
- 视图逻辑顺序错误:POST请求中先执行
form.save(commit=False)再做form.is_valid()校验,不符合Django表单校验规范,容易产生脏数据
修复步骤
1. 修正urls.py配置
from django.conf.urls import url, include from . import views app_name = 'Users' urlpatterns = [ url(r'^$', views.home, name='home'), # 优先匹配更具体的带参数路由,加结束符$,正则匹配2位大写字母的u_type url(r'^signUp/(?P<u_type>[A-Z]{2})/$', views.signup, name='signup_with_type'), # 再匹配无参数路由,加结束符$ url(r'^signUp/$', views.signup, name='signup'), url(r'^login/$', views.logedin, name='login') ]
给带参数的路由单独命名,避免和无参数路由重名冲突。
2. 修正SignUp.html的表单提交地址
<form action="{% url 'Users:signup_with_type' u_type=user_type %}" method="POST">{% csrf_token %}
3. 修正signup视图的逻辑顺序
def signup(request, u_type=''): if request.method == 'POST': form = SpaceUserForm(request.POST) # 先校验表单,再操作数据 if form.is_valid(): user = form.save(commit=False) user.user_type = str(u_type) user.save() login(request, user) return HttpResponse("User was created successfully.") else: return HttpResponse("There was an error.") else: context ={} if request.GET.get('addAgent'): user_type = 'AG' elif request.GET.get('addCustomer'): user_type = 'CU' elif request.GET.get('addWarehouseOwner'): user_type = 'WO' else: # 加默认值避免直接访问注册页时报错 user_type = '' context['form'] = SpaceUserForm() context['user_type'] = user_type return render(request, 'Users/SignUp.html', context)
可选更稳妥的实现方案
如果不想依赖URL参数传递角色值,也可以用表单隐藏字段实现,不需要修改路由配置:
- 在SignUp.html的表单中添加隐藏字段
<form action="{% url 'Users:signup' %}" method="POST">{% csrf_token %} <input type="hidden" name="user_type" value="{{ user_type }}"> <!-- 原有表单内容保持不变 --> </form>
- 视图POST分支直接读取POST参数即可
if form.is_valid(): user = form.save(commit=False) user.user_type = request.POST.get('user_type') user.save()
内容的提问来源于stack exchange,提问作者Ebin
相关产品推荐
相关产品推荐

