Django day03之学习知识点
今日是路由层学习:
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之学习知识点的更多相关文章
- django form使用学习记录
Django forms使用容易, 又方便扩展, 因此Django admin和CBVs基本都基于forms使用. 事实上, 由于django forms的强大验证功能, 大多数Django API ...
- Java编程学习知识点分享 入门必看
Java编程学习知识点分享 入门必看 阿尔法颜色组成(alpha color component):颜色组成用来描述颜色的透明度或不透明度.阿尔法组成越高,颜色越不透明. API:应用编程接口.针对软 ...
- Django RF:学习笔记(8)——快速开始
Django RF:学习笔记(8)——快速开始 安装配置 1.使用Pip安装Django REST Framework: pip install djangorestframework 2.在Sett ...
- Django 2.0 学习(07):Django 视图(进阶-续)
接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...
- Java程序设计学习知识点总结
Java程序设计学习知识点总结 Java语言简单,面向对象,分布式,解释性,健壮,安全与系统无关,可移植,高性能,多线程,动态语言. 什么是框架 可以认为是某种应用的半成品,就是一组组件用来完善自己的 ...
- Django 2.0 学习(04):Django数据库
数据库设置/配置 打开mysite/settings.py,我们会发现Django是用的是默认的数据库SQLite,如下图所示: Django也是支持其它数据库的,比如PostgreSQL.MySQL ...
- 【Django】 初步学习
这个系列(或者成不了一个系列..)预计会全程参考Vamei様的Django系列,膜一发.说句题外话,其实更加崇拜像Vamei那样的能够玩转生活.各个领域都能取得不小成就的人. [Django] ■ 概 ...
- 完整的Django入门指南学习笔记7 网页自动翻译
转自[https://simpleisbetterthancomplex.com/series/2017/10/16/a-complete-beginners-guide-to-django-part ...
- 完整的Django入门指南学习笔记5
前言 欢迎来到本系列教程的第5部分,在这节课,我们将学习如何保护视图防止未登录的用户访问,以及在视图和表单中访问已经登录的用户,我们还将实现主题列表和回复列表视图,最后,将探索Django ORM的一 ...
随机推荐
- Ubuntu 16.04上源码编译Poco并编写cmake文件 | guide to compile and install poco cpp library on ubuntu 16.04
本文首发于个人博客https://kezunlin.me/post/281dd8cd/,欢迎阅读! guide to compile and install poco cpp library on u ...
- Android开源项目和轮子
推荐查看Github最全面的Android开源项目汇总 功能框架 数据库 ORMLite框架 greenDaoMaster框架 Xutils的DButils ORMLitehe和greenDaoMas ...
- linux进程管理常用命令
初始化进程在centos5,6,7中的发展: 在centos5中使用sysv init 是一个shell脚本,依靠依次执行脚本中的命令启动系统,只能串行执行. 在centos6中使用upstart,也 ...
- linux 相关零碎知识整理
1.启动bash shell 大部分linux系统启动用户命令行接口(cli)环境时使用默认的bash shell,在bash shell启动时,它将自动执行位于用户主目录下的.bashrc中的命令. ...
- webuploader 快速应用(C#)
百度的WebUploader前端插件作为目前比较好用且免费的附件上传工具,利用了断点续传特点实现了大文件上传功能,其更好的兼容性与界面效果完全可以替换掉IE的activex 上传控件.许多人或许还不知 ...
- 金蝶天燕中间拒绝put、delete请求解决方案
项目要求支持国产化,那就国产化呗!使用金蝶天燕中间件替代weblogic,一切部署好后发现所有以put.delete请求的按钮全部无效,原因是中间件配置文件默认拒绝put.delete请求 解决方案为 ...
- 【Android - 进阶】之PopupWindow的使用
创建一个类继承自PopupWindow,编写自定义的PopupWindow类.示例代码如下: import android.app.Activity; import android.graphics. ...
- Spring之junit测试集成
简介 Spring提供spring-test-5.2.1.RELEASE.jar 可以整合junit. 优势:可以简化测试代码(不需要手动创建上下文,即手动创建spring容器) 使用spring和j ...
- Vue + TypeScript 踩坑总结
vue 和 TypeScript 结合的情况下,很多写法和我们平时的写法都不太一样,这里总结我项目开发过程中遇到的问题和问题的解决方案 有些问题可能还没解决,欢迎各位大佬给与提点. 另外,使用本文前可 ...
- JQuery之选择集过滤
JQuery选择集过滤应用如下: 代码实现: <script src="JS/jquery-3.4.1.js"></script> <script&g ...