今日是路由层学习: 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. Flutter学习笔记(30)--Android原生与Flutter混编

    如需转载,请注明出处:Flutter学习笔记(30)--Android原生与Flutter混编 这篇文章旨在学习如何在现有的Android原生项目上集成Flutter,实现Android与Flutte ...

  2. AppBoxFuture: 集成第三方Sql数据库

      框架设计之初是不准备支持第三方数据库的,但最近几个朋友都提到需要将旧的基于传统Sql数据库的应用迁移到框架内,主要是考虑到一方面目前框架内置的分布式数据库尚未完善,另一方面是希望能逐步迭代旧应用替 ...

  3. 小程序取消IOS虚拟支付解决方案

    前因 本来我们的小程序用的好好的,结果突然有一天,微信就把小程序的ios端的虚拟支付给关了...坑爹啊!搞的安卓端的可以支付,ios的支付不了.于是就在网上找解决办法. 一说通过app跳转支付,总不能 ...

  4. Java的 FileWriter类 和 FileReader类

    一.FileReader类1,构造方法:FileReader fr = new FileReader(String fileName);//使用带有指定文件的String参数的构造方法.创建该输入流对 ...

  5. SpringBoot 整合 Zookeeper 接入Starring微服务平台

    背景 最近接的一个项目是基于公司产品Starring做的微服务支付平台,纯后台项目,实现三方支付公司和银行接口来完成用户账户扣款,整合成通用支付接口发布给前端调用. 但是扯蛋了,这边前端什么都不想做, ...

  6. Docker harbor 安装和基础操作

    目录 简介 离线安装 配置文件 安装 查看 访问测试 及 简单操作 创建一个用户 创建一个测试仓库 创建测试仓库 测试上传和下载镜像 上传 下载镜像测试 简介 Docker容器应用的开发和运行离不开可 ...

  7. Docker 自建私有Registry 私有仓库

    目录 说明 介绍 原理 搭建 查看配置文件 启动 上传和下载镜像测试 测试上传镜像 测试下载镜像 说明 记录搭建 docker 私有仓库步骤 介绍 docker镜像可以托管到dockerhub中,跟代 ...

  8. mybatis中因为不理解$与#而出现的bug

    最近项目中遇到一个bug,正常的流程是这样的:要上传一个应用,首先检查系统中是否已经存在这个应用的更高版本,如果存在,则上传操作将被取消. bug体现为当传入系统中存在的所有应用与新上传的应用的ver ...

  9. 浅析babel产出

    (function(modules) { // 缓存对象 var installedModules = {}; // require方法 function __webpack_require__(mo ...

  10. SpringBoot原理讲解

    一.问题的引入 首先我们来看一个最简单的例子. 我们先创建一个SpringBoot的工程,如何创建一个SpringBoot工程就不说了,不会请自行解决.然后写一个controller类,通过请求路径, ...