• 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()
                
                
                
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  • 相关阅读:
    python之数据结构汇总
    【JDBC核心】数据库连接池
    【JDBC核心】数据库事务
    【JDBC核心】批量插入
    【JDBC核心】操作 BLOB 类型字段
    【JDBC核心】获取数据库连接
    【JDBC核心】JDBC 概述
    【Java基础】基本语法-程序流程控制
    【Java基础】基本语法-变量与运算符
    【Java基础】Java 语言概述
  • 原文地址:https://www.cnblogs.com/ludundun/p/11938228.html
Copyright © 2020-2023  润新知