Django+htmx未登录时URL模板标签缺省变量报错的简洁解决方法
问题
我用Django结合htmx开发项目,配置了如下路由:
urlpatterns = [ path('@/<username>/my_orders/', views.myordersview, name="myorders"), ]
视图函数myordersview添加了@login_required装饰器:
@login_required def myordersview(request, username): if request.htmx: return render(#something) else: return render(#something else)
在frame.html里通过htmx的a标签调用该路由:
<a hx-target="#content" hx-get="{% url 'myorders' user.username %}"> My Orders </a>
需求是未登录状态下仍显示该a标签,未认证用户点击后重定向到登录页,但未登录时user.username为空,导致Django报错:
Reverse for 'myorders' with arguments '('',)' not found.
不想用这种冗余写法:
<a hx-target="#content" hx-get=" {% if user.is_authenticated %} {% url 'myorders' user.username %} {% else %} {% url 'login' %} {% endif %} "> My Orders </a>
求无需自定义模板标签的简单解决方法?
解决方案
方法1:新增无参数路由,让视图自动补全用户信息
修改路由配置,新增一个无参数的路由指向同一个视图:
urlpatterns = [ path('@/<username>/my_orders/', views.myordersview, name="myorders"), # 新增无参数路由 path('my_orders/', views.myordersview, name="myorders_redirect"), ]
模板里直接使用这个无参数路由:
<a hx-target="#content" hx-get="{% url 'myorders_redirect' %}"> My Orders </a>
调整视图,自动获取当前登录用户的用户名:
@login_required def myordersview(request, username=None): # 若未传用户名,直接取当前登录用户的 username = username or request.user.username if request.htmx: return render(#something) else: return render(#something else)
未登录用户点击时,会被@login_required直接重定向到登录页,登录后自动跳转到正确的用户订单页面。
方法2:用as标签结合过滤器简化模板逻辑
利用Django模板的as语法捕获路由反向解析结果,再用default过滤器处理空值情况:
{% url 'myorders' user.username as myorders_url %} {% url 'login' as login_url %} <a hx-target="#content" hx-get="{{ myorders_url|default:login_url }}"> My Orders </a>
未登录时user.username为空,myorders_url会解析失败变为空字符串,此时default过滤器会自动替换成登录页的URL。
方法3:用占位符绕过解析错误,再在视图内修正
模板里给username传一个占位符,避免解析报错:
<a hx-target="#content" hx-get="{% url 'myorders' user.username|default:'temp' %}"> My Orders </a>
视图内判断并修正请求路径:
@login_required def myordersview(request, username): # 如果是占位符或用户名不匹配,重定向到正确路径 if username != request.user.username or username == 'temp': return redirect('myorders', request.user.username) if request.htmx: return render(#something) else: return render(#something else)
未登录用户点击后,@login_required会先重定向到登录页,登录后跳转到带占位符的地址,视图再自动修正为当前用户的订单页。
内容的提问来源于stack exchange,提问作者pepsizero
相关产品推荐
相关产品推荐

