路由简单配置一:有名分组、路由分发、登录验证示例、反向解析(流程控制)
2.路由配置-有名分组
还是直接上代码:
urls.py 全局
from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
# 这里介绍一种键值对的方式传参,固定格式,
# 在对应的分组名(相关括号开头的位置)加入?P<key>,如下(P为大写)
re_path(r'^articles/(?P<k1>[0-9]{4})/(?P<k2>[0-9]{2})/(?P<k3>[0-9]{2})/$', views.key_value_archive),
#key_value_archive(k1=匹配值,k2=匹配值,k3=匹配值)
]
views.py 对应项目中
from django.shortcuts import render,HttpResponse
# HttpResponse 响应对象
def key_value_archive(request,k2,k3,k1):
return HttpResponse('%s-%s-%s' %(k1,k2,k3))
3.路由控制-分发
一个项目一般有很多应用,如果所有的应用的路由列表都写在你一堆,效率肯定不高。
解决办法是在对应的app文件里面新建一个urls.py,再将对应的总urls.py中对应的代码拷贝过去
上代码
总控制文件夹中(这里以first_pro为例)的urls.py 全局
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
# 路由分发:
# 先得导入import include这个模块,专门搞路由分发功能的
re_path(r'^app01/',include('app01.urls'))
# 访问得加app01了如 http://127.0.0.1:8000/app01/articles/2018/06/27/
]
项目文件夹app01中的urls.py 项目局部
from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
re_path(r'^articles/(?P<k1>[0-9]{4})/(?P<k2>[0-9]{2})/(?P<k3>[0-9]{2})/$', views.key_value_archive),
]
项目app01中的views.py
from django.shortcuts import render,HttpResponse
# HttpResponse 响应对象
def key_value_archive(request,k2,k3,k1):
return HttpResponse('%s-%s-%s' %(k1,k2,k3))
4.路由控制-登录验证
首先,将settings.py中的一个东西注释掉
MIDDLEWARE = [
...
#'django.middleware.csrf.CsrfViewMiddleware',
# 将这个注释掉,更改默认的报错Forbidden (403)(后面会详细讲)
...
]
first_pro\urls.py 全局
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
# 登录验证
# re_path 可以加正则,
# path 不能加正则,否则匹配不到页面(后面会介绍)。
re_path(r"^login/",views.login),
]
views.py 对应项目中
# 登录验证
def login(request):
# request.method 的值为GET 或者POST,根据对应的方法选择不同的功能
if request.method == 'GET':
return render(request,'login.html')
else:
# request.GET 是一个字典,存放get请求中所有的数据
# request.POST 是一个字典,存放POST请求中所有的数据
user = request.POST.get('user')
pwd = request.POST.get('pwd')
if user == 'yuan' and pwd == 'abc123':
# HttpResponse 响应对象,再次封装,不能添加响应头和响应首行。
return HttpResponse('登录成功!')
else:
return HttpResponse('sorry!')
templates\login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#action或者src或者href里面不写ip地址等,默认会加上本次页面的地址, 末尾还必须加 /,否则会报RuntimeError at /login错#}
<form action="http://127.0.0.1:8000/login/" method="post">
用户名:<input type="text" name="user">
密码:<input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>
5.路由控制-反向解析
urls.py 全局中演示
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
# 反向解析:防止urls.py中的re_path被更改,而相应的html中的访问路径写死了,不好维护。
# 加个别名name = 'Log'
# 在对应的html文件中更改,比如action="{% url 'Log' %}" src和url也行。
path("login/", views.login, name='Log'),
path("timer/", views.timer, name='Tim'),
# 在html文件中写的比如{{}},{% url 'Log' %}之内的东西,Django在发送这个文件的时
# 候会自己渲染一遍html文件,替换其中的内容,在发给客户端
views.py与settings.py
与登录验证对应的代码一模一样!这里就略了!
templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#action或者src或者href里面不写ip地址等,默认会加上本次页面的地址, 末尾还必须加 /,否则会报RuntimeError at /login错#}
<form action="{% url 'Log' %}" method="post">
用户名:<input type="text" name="user">
密码:<input type="password" name="pwd">
<input type="submit">
</form>
<a href="{% url 'Tim' %}">哈哈</a>
</body>
</html>
6.流程控制-反向解析
first_pro\urls.py 全局-路由分发
from django.contrib import admin
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [re_path(r'^app01/',include('app01.urls')),]
app01/urls.py 项目
from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
# 添加一个名字name='s_c_2003',
re_path(r'^articles/2003/$', views.special_case_2003,name='s_c_2003'),
re_path(r'^articles/([0-9]{4})/$', views.year_archive,name = 'y_a'),
]
views.py 对应项目中
from django.shortcuts import render,HttpResponse
from django.urls import reverse
# HttpResponse 响应对象
# reverse是反向解析的函数
# 反向解析
def special_case_2003(request):
url = reverse('s_c_2003')
# 反向解析reverse会从全局~局部找该名字对应的url
print(url)
# 测试http://127.0.0.1:8000/app01/articles/2003/
# 打印的结果 /app01/articles/2003/
# url = reverse('y_a',)
# 由于y_a对应的路径有正则([0-9]{5}),这种执行条件下路径缺一个替换的参数,会报错!
url = reverse('y_a',args=(2014,))
# 传递一个参数,用于替换正则中相应匹配括号的位置
# 如果参数不匹配会报错 NoReverseMatch at.....
print(url)
# /app01/articles/2014/
return HttpResponse('special_case_2003')
def year_archive(request):
return HttpResponse('year_archive')