django 路由控制之反向解析
在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。
人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。
在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:
- 在模板中:使用url 模板标签。
- 在Python 代码中:使用
from django.urls import reverse()函数
反向解析第一种方法:
login.html
利用django 模板url 渲染 去找对应的name对应url 匹配住对应url 渲染到页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <form action="{% url 'logins' %}" method="post"> 用户名<input type="text" name="username"> 密码<input type="password" name="password"> <input type="submit"> </form> </body> </html>
urls.py
起个别名 url name="" 利用name 找对应url
from django.contrib import admin from django.urls import path, re_path, include from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path("login/", views.login, name="logins"), # 分发 re_path(r"^", include("app01.urls")), ]
views.py
from django.shortcuts import render, HttpResponse # Create your views here. def login(request): if request.method == "GET": return render(request, "login.html") elif request.method == "POST": username = request.POST.get("username") password = request.POST.get("password") if username == "mike" and password == "123": return HttpResponse("登录成功") else: return HttpResponse("用户名或者密码错误")
url 模板 另外一种写法
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> <ul> {% for yearvar in year_list %} <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li> {% endfor %} </ul>
当命名你的URL 模式时,请确保使用的名称不会与其它应用中名称冲突。
如果你的URL 模式叫做comment
,而另外一个应用中也有一个同样的名称,当你在模板中使用这个名称的时候不能保证将插入哪个URL。
在URL 名称中加上一个前缀,比如应用的名称,将减少冲突的可能。我们建议使用myapp-comment
而不是comment
。
反向解析第二种方法
在python中:
from django.urls import reverse from django.http import HttpResponseRedirect def redirect_to_year(request): # ... year = 2006 # ... return HttpResponseRedirect(reverse('news-year-archive', args=(year,))) # 同redirect("/path/")