今日是路由层学习: 3.路由匹配
3.1 正则表达式的特点:
一旦正则表达式能够匹配到内容,会立刻结束匹配关系
直接执行对应的函数。相当于采用就近原则,一旦找到就不再继续往下走了
重点:
正则表达式开头用 ^ 表示 (开头必须要有)
正则表达式结尾用 $ 表示
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/', views.test),
url(r'^testadd/', views.testadd),
] 3.2 settings.py文件中配置请求的访问路径自动加斜杠的功能
默认情况下,是TRUE。
#取消django自动让浏览器加斜杠的功能
APPEND_SLASH = False
添加配置后
例如:
http://127.0.0.1:8000/testadd进行请求会出现404页面
取消配置后,尾部django会自动添加/
http://127.0.0.1:8000/testadd/ 请求访问成功 举例:
1.路径如下:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'testadd/', views.testadd),
]
请求路径中的漏洞:
http://127.0.0.1:8000/wwwwwwwwwwwwwtestadd/
请求结果:请求成功
解决方法:
在url(r'testadd/', views.testadd)中的testadd/前部添加 ^ 符号
代表请求路径 从...开始
正确路径如下:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^testadd/', views.testadd),
] 2.路径如下:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^testadd/', views.testadd),
]
请求路径中的漏洞:
http://127.0.0.1:8000/testadd/wwwwwwwwww
请求结果:请求成功
解决方法:
在url(r'^testadd/', views.testadd)中的testadd/尾部添加 $ 符号
代表请求路径 以...结束
正确路径如下:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^testadd/$', views.testadd), ] 注意事项:
路由匹配只匹配请求的url路径部分,不匹配 ?后面的get携带的字段值参数,如下:
http://127.0.0.1:8000/testadd/?username=jsaon 4.无名分组---->用位置形参
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/([0-9]{4})', views.test),
url(r'^testadd/', views.testadd),
]
对应报错的语句:
url(r'^test/([0-9]{4})', views.test),
test() takes 1 positional argument but 2 were given
什么是无名分组?
当你的路由中有分组"([0-9]{4})"的正则表达式,那么在匹配到内容时执行函数的时候,
会将分组内正则表达式匹配到的内容当做位置参数传递给视图函数,那么
就需要在函数中添加一个形参,如下:
def test(request,分组对应的形参): 5.有名分组----->用关键字实参
(?P<year>\d+)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^testadd/(?P<year>\d+)', views.testadd),
] url(r'^testadd/(?P<year>\d+)', views.testadd),
testadd() got an unexpected keyword argument 'year' 什么是有名分组?
当你的路由中有分组并且给分组起了别名(year),那么在匹配内容的时候,
会将分组内的正则表达式匹配到的内容(year)当做关键字参数传递给视图函数,
def testadd(request,year):
year的值是用户在浏览器输入的url地址中对应的一块数据
比如用户输入的地址是:http://127.0.0.1:8000/testadd/2222,请求成功,
那么year对应的数据就是 year=2222
关键字参数:
def func(x,y):
print(x)
print(y)
func(x=1,y=2)
位置参数:
def func(x,y):
print(x)
print(y)
func(1,2) 利用有名和无名分组,我们就可以在调用视图函数之前给函数传递额外的参数。
django中有名分组和无名分组不能同时混合使用!!!
但是同一种分组的情况下,可以使用多次,
无名可以有多个,
有名可以有多个,
但是就是不能混合使用,其实写多个也没有啥意思,知道这种形式即可
url(r'^index/(\d+)/(\d+)/',views.index)
url(r'^index/(?P<args>\d+)/(?P<args>\d+)/',views.index) 6.第一种情况反向解析
(通俗)何为反向解析,就是通过A---->(访问到了)B去了!!!
(专业)何为反向解析,就是根据一个别名,动态解析出一个结果,
该结果可以最直接访问到对应的url 1.前端反向解析: 在html页面中编写
{% url 'xxx' %}
<p><a href="{% url 'xxx' %}">111111</a></p> 2.后端反向解析: 在views.py文件中编写
1.首先导入reverse模块:
from django.shortcuts import render,HttpResponse,redirect,reverse
2.在对应视图函数中编写后端反向解析代码
url=reverse('xxx') 7.第二种情况反向解析
1.无名分组的反向解析,在解析的时候,你需要手动指定正则匹配的内容是什么
url(r'^home/(\d+)', views.home,name='xxx'), Reverse for 'xxx' with no arguments not found. 1 pattern(s) tried: ['home/(\\d+)']
翻译:'xxx'的反转,没有找到参数。['home/(\\d+)'] 解决方法:
在前端对应的html文件中,解析代码中添加一个匹配正则的参数即可(例如:12)
{% url 'xxx' 12 %}
该数字通常是数据的主键值!!!
<p><a href="{% url 'xxx' 12 %}">111111</a></p>
注意事项:在后端views.py文件中配置一个位置参数(yyy)接收正则
def home(request,yyy):
return HttpResponse('Home')
综上所述,所以总结如下:
无名分组前端反向解析:
<p><a href="{% url 'xxx' 12 %}">111111</a></p> 无名分组后端反向解析:
后端反向解析需要后端views.py文件中,对应的函数中的位置参数匹配到正则表达式即可 通过访问http://127.0.0.1:8000/index/,点击'111111',跳转报错,
报错信息:home() takes 1 positional argument but 2 were given
原因是home函数缺少了一个位置参数,所以下面的home函数需要配置一个位置参数(yyy)
1.def home(request,yyy):
return HttpResponse('Home')
之后后端对应解析如下:
添加一个args=(参数,),注意括号内的逗号不能省略
2.def get_url(request):
url=reverse('xxx',args=(1,)) #必须加逗号,作为元组
print(url)
return HttpResponse('get_url,大宝贝')
在get _url函数中,如果反转解析忘记配置args =(参数,)了,就会报下面的错误:
Reverse for 'xxx' with no arguments not found. 1 pattern(s) tried: ['home/(\\d+)']
'xxx'的反转,没有找到参数。 8.第三种情况反向解析
无名分组不是真的无名,而是没有固定的名字;
有名分组是因为有固定不变的名字,所以称之为有名分组;
下面的知识点仅作了解:
1.有名分组的反向解析,在解析的时候,需要手动指定,正则匹配的内容是什么呢?
正规的写法是:
url(r'^home/(?P<year>\d+)', views.home,name='xxx'),
前端:
可以直接用无名分组的情况
<p><a href="{% url 'xxx' 12 %}">111111</a></p>
也可以使用规范的写法!!!书写麻烦了解即可
<p><a href="{% url 'xxx' year=1232 %}">111111</a></p> 后端:
可以直接用无名分组的情况
url=reverse('xxx',args=(1,))
也可以使用规范的写法!!!书写麻烦了解即可
url=reverse('xxx',kwargs={'year':666}) 9.无名有名反向解析结合使用
以编辑功能为例
url(r'^edit_user/(\d+)/',views.edit_user,name='edit') def edit_user(request,edit_id):
#edit_id就是用户想要编辑数据的主键值
pass
{% for user_obj in user_list %}
<a href='/edit_user/{{user_obj.id}}'>编辑</a>
<a href='{% url 'edit' user_obj.id %}'>编辑</a> #反向解析
{% endfor %} 10.路由分发
前提:
在django中所有的app都可以有自己独立的urls.py templates static文件
作用:为大项目解耦合,分功能开发,互相之间不干扰,每个人只负责自己的app即可
项目经理只需要将所有人开发的app整合到一个空的django项目中,
然后再settings配置文件注册,再利用路由分发将多个app整合到一起,
即可完成大项目的拼接。 路由分发解决的就是项目的总路由匹配关系过多的情况
使用路由分发,会将总路由不再做匹配的活而仅仅是做任务分发:
请求来了之后,总路由不做对应关系,只询问你要访问哪个app的功能,
然后将请求转发给对应的app去处理。
创建第二个app
1.Tools--->Run manage.py Task...
2.manage.py@day51 > startapp app02
然后在settings配置文件中配置对应app名字
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
'app02'
]
并分别在app下创建urls.py文件
3.
总路由只需要将所有的app的urls.py导入即可。
总路由中导入include模块:
from django.conf.urls import url,include
总路由中导入各个应用下的urls.py文件,as 是起别名:
from app01 import urls as app01_urls
from app02 import urls as app02_urls
在对应的应用下的urls.py文件中书写下面代码:
例如:app01应用的urls.py文件中书写:
from django.conf.urls import url
from app01 import views
urlpatterens = [
#这里面写该应用下的路由
url(r'^index/', views.index) ] 总路由分发:
总路由中使用include做分发
因为app01、app02下的路由、对应视图函数都含有def reg(request):函数,
所以总路由为了做好区分,在总路由中分别使用各个应用名的前缀来做区分, 笨方法总路由:
from django.conf.urls import url,include
from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls))
]
总路由分发注意事项:
总路由里面不能以 $ 符号结尾
在urlpatterns中r'^app02/'$(千万不能加$符号),不然路径都是匹配不上的
为了解决总路由中每次频繁导入app应用的问题:
django推出了最最简单的总路由分发方法:
特点:
1.无需频繁导入
2.不用频繁加应用名后缀
那么该方法是什么呢?
新方法总路由:
1.不要导入语句
2.不再使用应用名前缀,使用 (应用名.urls)
#from app01 import urls as app01_urls
#from app02 import urls as app02_urls
from django.conf.urls import url,include
urlpatterns = [
url(r'^app01/',include(app01.urls)),
url(r'^app02/',include(app02.urls))
]
||||||||||||||筛检上面不用的代码,如下:||||||||||||||||||
from django.conf.urls import url,include
urlpatterns = [
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
] 子路由app01:
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^reg/', views.reg),
] 子路由app02:
from django.conf.urls import url
from app02 import views
urlpatterns = [
url(r'^reg/', views.reg),
]
路由分发:
前提:
所有的app都可以有自己独立的urls.py templates模板文件夹 static静态文件夹
正是由于该特点,使得django实现多人开发 非常方便
每个人只需要开发自己的app即可 路由分发:
总路由不再直接做路由与试图函数对应关系了,而是仅仅做一个转发的功能
好处:更加的解耦合,更加好维护
from django.conf.urls import url,include
url(r'^应用名1/',include('应用名1.urls'))
url(r'^应用名2/',include('应用名2.urls')) 11.名称空间--了解知识点,记住最后面两句话
当不同的应用中给路由与视图对应关系起了相同的别民,在反向解析的时候,并不能
直接识别到时哪个应用下的
url(r'^应用名1/',include('应用名1.urls',namespace='应用名'))
{% url '应用名1:相同的别名' %}
{% url '应用名2:相同的别名' %} 记住这两句话:
你完全可以不使用名称空间,
你只需要保证在起别名的时候,不要出现冲突即可,
建议做法就是加 应用前缀_别名 12.虚拟环境
给每一个喜爱你干嘛提供一个专门属于该项目自己的所需模块,避免浪费,节省资源
requirement.txt
django==1.11.11
Flask==1.4
建议不要频繁的开设虚拟环境
虚拟环境创建中选择 New environment--->Make available to all projects django版本区别:
path 与 url
path 第一个参数不支持正则,如果你还想使用正则,你可以re_path和url是一模一样的
path虽然不支持正则,但是提供了五个默认的转换器,能够自动帮你转换数据类型
还支持用户自定义转换器 request方法获取文件数据:
request.FILES 获取form表单上传的文件数据 file_obj=request.FILES.get('myfile')
file_obj.name --->文件名 f=open(file.obj.name,'wb')
for chunk in file_obj.chunks():
f.write(chunk)
f.close()

Django day03之学习知识点的更多相关文章

  1. django form使用学习记录

    Django forms使用容易, 又方便扩展, 因此Django admin和CBVs基本都基于forms使用. 事实上, 由于django forms的强大验证功能, 大多数Django API ...

  2. Java编程学习知识点分享 入门必看

    Java编程学习知识点分享 入门必看 阿尔法颜色组成(alpha color component):颜色组成用来描述颜色的透明度或不透明度.阿尔法组成越高,颜色越不透明. API:应用编程接口.针对软 ...

  3. Django RF:学习笔记(8)——快速开始

    Django RF:学习笔记(8)——快速开始 安装配置 1.使用Pip安装Django REST Framework: pip install djangorestframework 2.在Sett ...

  4. Django 2.0 学习(07):Django 视图(进阶-续)

    接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...

  5. Java程序设计学习知识点总结

    Java程序设计学习知识点总结 Java语言简单,面向对象,分布式,解释性,健壮,安全与系统无关,可移植,高性能,多线程,动态语言. 什么是框架 可以认为是某种应用的半成品,就是一组组件用来完善自己的 ...

  6. Django 2.0 学习(04):Django数据库

    数据库设置/配置 打开mysite/settings.py,我们会发现Django是用的是默认的数据库SQLite,如下图所示: Django也是支持其它数据库的,比如PostgreSQL.MySQL ...

  7. 【Django】 初步学习

    这个系列(或者成不了一个系列..)预计会全程参考Vamei様的Django系列,膜一发.说句题外话,其实更加崇拜像Vamei那样的能够玩转生活.各个领域都能取得不小成就的人. [Django] ■ 概 ...

  8. 完整的Django入门指南学习笔记7 网页自动翻译

    转自[https://simpleisbetterthancomplex.com/series/2017/10/16/a-complete-beginners-guide-to-django-part ...

  9. 完整的Django入门指南学习笔记5

    前言 欢迎来到本系列教程的第5部分,在这节课,我们将学习如何保护视图防止未登录的用户访问,以及在视图和表单中访问已经登录的用户,我们还将实现主题列表和回复列表视图,最后,将探索Django ORM的一 ...

随机推荐

  1. Video的自我学习

    直播原理 视频协议 HLS协议  [主要是直播方面(好用,但延时)] HTTP Live Streaming(缩写是HLS)是一个由苹果公司提出的基于HTTP的流媒体网络传输协议. 是苹果公司Quic ...

  2. 线程同步&线程池

    线程同步&线程池 线程同步 线程不同步会出现的问题: 当多个线程操作同一资源时,会出现重复操作和和操作不存在的资源的问题,为了规避这一问题就需要线程的同步操作来实现资源的共同使用. 线程同步: ...

  3. android 网络异步加载数据进度条

    ProgressDialog progressDialog = null; public static final int MESSAGETYPE = 0; private void execute( ...

  4. Appium自动获取 Android 设备 id 和包名等信息(python)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/zhusongziye/article/d ...

  5. nginx集群架构

    Linux集群从功能分类 高可用集群,高可用集群通常为俩台服务器,一台工作,另一台冗余,当提供服务器的服务器宕机时候,冗余服务器将接替宕机的服务器继续提供服务.实现高可用的集群开源软件有Heatbea ...

  6. php弹出确认框

    下面的代码只需要放在同一个文件中就可以运行了~~ html<a href="__URL__/shanchu/id/{$vo.id}" onclick='return del( ...

  7. C语言I博客作业01

    C语言I博客作业01 作业1 这个作业属于哪个课程? C语言程序设计I 这个作业要求在哪里? https://edu.cnblogs.com/campus/zswxy/CST2019-2/homewo ...

  8. python_网络编程

    网络ISO(国际标准化组织)--->网络体系结构标准(OSI模型)OSI: 网络信息传输比较复杂需要很多功能协同-->将功能分开,降低耦合度,让每个模块完成一定的功能-->将这些模块 ...

  9. MQTT版本升级过程及源码解析

    MQTT版本升级过程及源码解析 首先说一下为什么要写这篇文章呢,在我发现网上对MQTT的文章介绍实在太少了,可能也是使用这个的频率比较低吧!还有对问题的定位以及解决的方式和办法也太少了,所以特意写这篇 ...

  10. Codeforces Round #452 (Div. 2) A B C

    Codeforces Round #452 (Div. 2) A Splitting in Teams 题目链接: http://codeforces.com/contest/899/problem/ ...