zoukankan      html  css  js  c++  java
  • Django(命名空间)

    命名空间

    命名空间(英语:Namespace)是表示标识符的可见范围。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其它命名空间中。 由于name没有作用域,Django在反解URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,立即返回 我们在开发项目时,会经常使用name属性反解出URL,当不小心在不同的app的urls中定义相同的name时,可能会导致URL反解错误,为了避免这种事情发生,引入了命名空间。

    项目urls.py

    from django.urls import path
    from  myapp import views
    from  django.conf.urls.static import static
    from  django.conf import settings
    from  django.conf.urls import re_path,include
    from  myapp import *
    from  myapp02 import *
    urlpatterns  = [
        # path('admin/', admin.site.urls),
        path('hello/',views.hello),
        path('login/',views.login,name ='Log' ),
        re_path(r"^myapp/",include(("myapp.urls","myapp"))), #这里记住是元组,然后后面是名称
        re_path(r"^myapp02/",include(("myapp02.urls","myapp02"))),
    
    ]+ static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)

    app1 urls.py

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from  django.conf.urls import url
    from myapp import views
    from  django.urls import re_path
    urlpatterns  = [
    
        re_path(r'^index/',views.index,name='index'),
        url(r'^hello/([0-9]{4})/$', views.year_archive,name='y'),
        url(r'^hello/([0-9]{4})/([0-9]{2})/$', views.month_archive),
        url(r'^hello/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
    ]

    app1 views.py

    from django.shortcuts import render
    from django.http import HttpResponse
    from  django.urls import reverse
    # Create your views here.
    # request 是固定写法
    def index(request):
        return HttpResponse(reverse("myapp:index"))

    app2 urls.py

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from myapp02 import views
    from  django.urls import re_path
    urlpatterns  = [
    
        re_path(r'^index/',views.index,name='index'),
        ]

    app2 views.py

    from django.http import HttpResponse
    from  django.urls import reverse
    def index(request):
        return HttpResponse(reverse("myapp02:index"))

     思考情况如下:

    urlpatterns = [
    re_path('articles/(?P<year>[0-9]{4})/', year_archive),
    re_path('article/(?P<article_id>[a-zA-Z0-9]+)/detail/', detail_view),
    re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/edit/', edit_view),
    re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/delete/', delete_view),
    ]

    考虑下这样的两个问题: 第一个问题,函数 year_archive 中year参数是字符串类型的,因此需要先转化为整数类型的变量值,当然year=int(year) 不会有诸如如TypeError或者ValueError的异常。那么有没有一种方法,在url中,使得这一转化步骤可以由Django自动完成? 第二个问题,三个路由中article_id都是同样的正则表达式,但是你需要写三遍,当之后article_id规则改变后,需要同时修改三处代码,那么有没有一种方法,只需修改一处即可? 在Django2.0中,可以使用 path 解决以上的两个问题。

    基本示例

    这是一个简单的例子:

    from django.urls import path  
    from . import views  
    urlpatterns = [  
        path('articles/2003/', views.special_case_2003),  
        path('articles/<int:year>/', views.year_archive),  
        path('articles/<int:year>/<int:month>/', views.month_archive),  
        path('articles/<int:year>/<int:month>/<slug>/', views.article_detail),  
    ]

    基本规则:

    1. 使用尖括号(<>)从url中捕获值。
    2. 捕获值中可以包含一个转化器类型(converter type),比如使用 捕获一个整数变量。若果没有转化器,将匹配任何字符串,当然也包括了 / 字符。
    3. 无需添加前导斜杠。

    以下是根据https://docs.djangoproject.com/en/2.0/topics/http/urls/#example而整理的示例分析表:

     

    path转化器
    文档原文是Path converters,暂且翻译为转化器。
    Django默认支持以下5个转化器:

    1. str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
    2. int,匹配正整数,包含0。
    3. slug,匹配字母、数字以及横杠、下划线组成的字符串。
    4. uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
    5. path,匹配任何非空字符串,包含了路径分隔符

    注册自定义转化器
    对于一些复杂或者复用的需要,可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:

      1. regex 类属性,字符串类型
      2. to_python(self, value) 方法,value是由类属性 regex 所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。
      3. to_url(self, value) 方法,和 to_python 相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。

    例子:

    class FourDigitYearConverter:  
        regex = '[0-9]{4}'  
        def to_python(self, value):  
            return int(value)  
        def to_url(self, value):  
            return '%04d' % value

    使用register_converter 将其注册到URL配置中:

    from django.urls import register_converter, path  
    from . import converters, views  
    register_converter(converters.FourDigitYearConverter, 'yyyy')  
    urlpatterns = [  
        path('articles/2003/', views.special_case_2003),  
        path('articles/<yyyy:year>/', views.year_archive),  
        ...  
    ]

    路由层总结

        基于之前的章节,把路由层(path分发)一些基本的东西都学完了,稍作梳理如下

        --->通过django 1的re_path,可以写正则匹配路径,让一大堆类型相同的path都简写成一个正则匹配的path

            大大的减少了代码量如果要从path中取值,就在它周围加上括号(),取值之后,对应的处理函数就要写

            参数来接收这个值。

        --->有名分组:可以使用命名的正则表达式组来捕获URL 中的值并以关键字参数传递给视图,就是在正则匹配项

        前面,加上?P<name>的方式为这个值取个别名,类似python的关键字参数,取名之后,传参就必须“指名道姓”了,

        处理函数的参数就必须是这个别名,不能是别的,可以打乱位置,否则会报错。

        --->路由分发:当urls.py的path越来越多,后期管理就尤为不便,于是引入了路由分发功能,简言之,就是在每个应用

        下面增加自己的urls.py文件,用来存在本应用相关的path,项目urls.py就存放一些主页/一级菜单等等的path,其他的

        通过include函数做分发,这样可以提升代码/path的层级关系,后期管理更方便。

        --->反向解析:从一个登陆验证的功能,引入反向解析的概念,之前登陆页面表单提交,action部分是写死的path路径,

        当我主urls.py的path变化之后,得找到这些引用的地方一个一个的去改,着实麻烦且易出错,反向解析就是先给主

        urls.py的path定义个别名,其他地方通过特定的格式引用这个别名就行了,这样主urls.py的path不管怎么变,其他引用的

        地方都不必再改变或操心这些事。因为你别名不变,那么,引用的时候就能指到这个(最新的)path。

        --->名称空间,通过反向解析别名重名的问题,引入名称空间,类似于如果有两个不一样的app下面都取了“张三”代指

        一个path,而这个别名是全局性的,反向解析时就会去找,找到一个便返回,就自始至终只能找到一个“张三”的问题,

        名称空间相当于给每个“张三”再加个标识,比如这是“房间1的张三”,那是“房间2的张三”,也就是限定别名的作

        用域,这样,反向解析就能找到对应的/正确的哪个“张三”。

        --->Django 2的path,相比1版本的优化点,列举了两个,一是取值形式,之前是(),现在是尖括号<>。

        二是取值的类型转换,之前取回来的值,一些看起是int的值,其实类型是str,需要再函数里面手动转换,

        现在直接在path里面,增加转换器,实现一些字符的转换功能。

        然后就是本章的,若是这些django的内置转换器不够用,就自己定义转换器,引用前需注册,取别名,再通过别名调用。

  • 相关阅读:
    POJ 1811 Prime Test 素性测试 分解素因子
    sysbench的安装与使用
    电脑中已有VS2005和VS2010安装.NET3.5失败的解决方案
    I.MX6 show battery states in commandLine
    RPi 2B Raspbian system install
    I.MX6 bq27441 driver porting
    I.MX6 隐藏电池图标
    I.MX6 Power off register hacking
    I.MX6 Goodix GT9xx touchscreen driver porting
    busybox filesystem httpd php-5.5.31 sqlite3 webserver
  • 原文地址:https://www.cnblogs.com/mjiu/p/9648037.html
Copyright © 2011-2022 走看看