Routing layer 003 Django framework

A routing layer (the urls.py)

It refers to the routing file in Django urls.py called routing layer

Routing layer that is requested by the user mapping between the address and view function , if a website is likened to a dictionary, then our routing (urls.py) than on the number of directory is the dictionary, Django routed in the default file in urls.py in the following figure:

Second, the simple routing configuration

# urls.py路由配置文件
from Django.conf.urls import url

# 有一条条映射关系组成的urlpatterns这个列表称之为路由表
urlpatterns = [
    url(regex,view,kwargs=None,name=None),
    #url本质就是一个函数
]

Function key parameters introduced url:

  • regex: regular expression used to match clients to access the url address portion of the path
    • For example: url address is http: //127.0.0.1:8000/index/, regular expressions to match part of index /
  • view: usually url is a view corresponding function to process business logic
  • kwargs: slightly (see usage famous grouping)
  • name: slightly (see the use of reverse lookup)

Case are as follows:

# urls.py文件

from django.conf.urls import url
from django.contrib import admin
from app01 import views # 导入视图函数模块views.py

urlpatterns = [
    url(r'^admin/',admin.site.urls),# 这里是新建一个django项目默认自带的,不用管它
    
    url(r'^index/$',views.index),#这是新增的一条地址与视图函数的对应关系
]
# views.py视图函数文件

from django.shortcuts import render 
from django.shortcuts import redirect
from django.shortcuts import HttpResponse # 导入HttpResponse,用来生成响应信息,就是直接可以返回字符串,将字符串处理过后响应给客户端

def index(request):
    return HttpResponse('这是index.page')

Tests are as follows:

# 启动服务端方式一:命令行
-->:python manage.py runserver 8001 # 这里启动的时候,可以指定端口号:8001,默认为8000
在浏览器中输入http://127.0.0.1:8001/index/ 就会看到‘我是index.page’    
    
    
# 启动服务端方式二:直接在pycharm窗口中启动
-->:这里要提前在下图中进行配置:

pycharm window: Start Django project server side methods below:

2.1 Note one

We just enter in your browser: Http: //127.0.0.1:8001/index/, Django will be holding a portion of the path index / to the routing table (urls.py file) in the top-down match the regular expression, once the match is successful , will be immediately executed path corresponding to the view function , the above list is uelspatterns routing table (the urls.py file) in url('^index/$',views.index)----- index function is a function of the file view views.py

2.2 Note two

When we entered in the browser: Http: //127.0.0.1:8001/index,Django index will also hold part of the path to the routing table from top to bottom to match the regular expression, looks like not match the regular expression formula (r '^ index / $' match must end with a /, it must be matched to the success index), but in fact we are still in the browser to see the wide mouth 'I am indexpage', for the following reasons:

In the configuration file has a parameter APPEND_SLASH settings.py in which a linked parameter values True / False:

  • When APPEND_SLASH = True (if the configuration is not the configuration file, the default value True), and the address path portion url requested by the user is not / at the end, for example, the address request url: Http: //127.0.0.1:8001 / index, Django will be holding a portion of the address to the routing table index matching regular expression match is found unsuccessful, Django will be added after the path / (index /) to match the routing table, not been matched yet would return path can not be found, if the match is successful, it will return a redirect message to the browser, the browser requires to re-Http: //127.0.0.1:8001/index/ address foldback request.
  • When APPEND_SLASH = False, the above-described process is not performed, but the path that is part of the url of the match fails immediately return path strength is not found, it will not do any additional operation

Third, routing packets

What is a packet, the packet why should it?

For example, we developed a blog system, when we need to see specific articles based on the id of the article , the browser needs to pass parameters (id number of the article) to designate field when sending a request, can be used Http: //127.0.0.1:8001 / article / id = 3, the parameters can also directly into the path Http:? //127.0.0.1:8001/article/3/

Django will need to get a way for the parameters directly from the Road King, which uses grouping features of regular expressions, and divided into two groups: the unknown and famous grouping grouping

3.1 anonymous group

# urls.py文件

from django.conf.urls import url
from django.contrib import admin
from app01 import views # 添加app001应用中的views视图函数文件

urlpatterns = [
    url(r'^admin',admin.site.urls),
    
    # 下面的正则表达式会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以位置参数的形式传给视图函数,有几个分组就传几个位置参数
    url(r'aritcle/(\d+)/$',view.article),#(\d+)代表匹配数字1-无穷个
]
# views.py视图文件

from django.shortcuts import render
from django.shortcuts import HttpResponse

# 需要额外增加一个形参用于接收传递过来的分组数据
def article(request,article_id):
    return HttpResponse('id为 %s 的文章内容....' %article_id)
# 测试
python.manage.py runserver 8001 
在浏览器输入:http: //127.0.0.1:8001/article/3 会看到:id为3的文章内容....

3.2 famous grouping

# urls.py文件
from django.conf.urls import url
from django.contrib import admin
from app01 import views # 添加app001应用中的views视图函数文件

urlpatterns = [
    url(r'^admin',admin.site.urls),
    
    # 下面的正则表达式会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以关键字参数(article_id=..)的形式传给视图函数,有几个分组就传几个关键字参数
    url(r'aritcle/(?P<article_id>\d+)/$',view.article),#(\d+)代表匹配数字1-无穷个
]
# views.py视图文件

from django.shortcuts import render
from django.shortcuts import HttpResponse

# 需要额外增加一个形参用于接收传递过来的分组数据
def article(request,article_id):
    return HttpResponse('id为 %s 的文章内容....' %article_id)
# 测试
python.manage.py runserver 8001 
在浏览器输入:http: //127.0.0.1:8001/article/3 会看到:id为3的文章内容....

The difference between 3.3 and famous anonymous grouping grouping

Unknown packets and known packets are acquired for the path parameters, and passed to the view, the differences are as follows:

  1. Packet is transmitted in the form of unknown position parameters corresponding to the view function, unknown at this time there are several packets in a regular (the urlpatterns) in the routing table, then the function corresponding view, there should be some positional parameters to receiving, in the above example, only one unknown packet 3, the transfer function is to view (views.article (request, '3'))
  2. Known form of packet is transferred to the corresponding keyword parameters view function, in which case there are several known in the regular packet (the urlpatterns) in the routing table, then the corresponding view function may be used ** kwargs to collect parameter may be directly written in the form of a keyword parameters, the above example isviews.article(request,article_id='3')

Note: nameless group and also known as packet do not mix

Fourth, route distribution

With the increased functionality of Django project, the app will be more and more applications, the route will be more and more, each app will have their own routes, if revisit all routes in a routing table, will lead structure is not clear, not easy to maintain and manage the project, so we should own the app to manage their own routing handed over, and then total the routing table to do the distribution, specific practices are as follows:

4.1 create two app

# 新建项目mysite1---此处用命令行命令创建
# 切换到存储项目的目录下
django-admin startproject mysite1

# 切换到新建的项目下
# 创建两个app项目(app01和app02)
python3 startapp app01
python3 startapp app02

Note here that the following three points:

  1. I used the command line to create a django project, you need to manually create your own Templates .html file folder to store the need to use
  2. And to the settings of TEMPLATES configuration: 'DIRS': [os.path.join ( BASE_DIR, 'templates')]
  3. In the settings INSTALLED_APPS are arranged to 'app01' 'app02'

4.2 manually created in the app store in their routing urls.py

urls.py routing table file 1. app01 under

from django.conf.urls import url
# 导入app01 的views
from app01 import views

urlpatterns = [
    url(r'^index/$',views.index),
]

views.py view function files under app01

from django.shortcuts import render
from django.shortcuts import HttpResponse

def index(request):
    return HttpResponse('我是app01下的index页面。。。。。')

2. app02 urls.py routing table files in the

from django.conf.urls import url

# 导入app02 的views
from app02 import views

urlpatterns = [
    url(r'^index/$',views.index),
]

views.py view function files under app02

from django.shortcuts import render
from django.shortcuts import HttpResponse

def index(request):
    return HttpResponse('我是app02下的index页面。。。。。')

Routing Table 4.3 Total mysite1 folder urls.py

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    # 因为功能太多,所以在总的路由表中,做路由分发,分发给各个app功能应用
    # 新增的两条路由,注意不能以$结尾
    # include函数就是做分发操作的,当浏览器输入http://127.0.0.1:8001/app01/index时
    # 会先进入到总路由表中进行匹配,正则表达式r'^app01/'会先匹配成功路径app01/
    # 然后include功能函数就会去app01下的urls.py中继续匹配剩余的路径部分
    url(r'app01/',include('app01.urls')),
    url(r'app02/',include('app02.urls'))
]

test:

# 先启动项目server端---命令行式:python manage.py runserver 8001
1.在浏览器中输入:Http://127.0.0.1:8001/app01/index/ 
  会看到我是app01下的index页面。。。

2.在浏览器中输入:Http://127.0.0.1:8001/app02/index/ 
  会看到我是app02下的index页面。。。

Fifth, reverse analysis

Question: In the early days of software development, design path url address may not be perfect, the latter need to be adjusted if the project in many places are used to change the path, once the path has changed, it means that all uses are changed paths need to be modified, this is a very troublesome operation.

Solution: When is writing a url (regex, view, kwargs = None, name = None), by parameter name for the path part of the url address an alias, the project can be obtained through this path alias. No matter what changes take place in the future path of the alias and the path is always consistent.

Such a path acquired through the above-described process is called reverse DNS alias: That is, the reverse path to access this address is resolved by a series of string

Case: After a successful login Jump to page index.html

# urls.py路由文件中

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/',admin.site.urls),
    
    # login/别名的为login_page
    url(r'^login/$',views.login,name='login_page'),
    
    # index/别名的为index_page
    url(r'^index/$',views.index,name='index_page'),
]
# views.py视图函数文件中

from django.shortcuts import render
from django.shortcuts import reverse
from django.shortcuts import redirect
from django.shortcuts import HttpResponse

def login(request):
    if request.method == 'GET':
        # 当为浏览器为get请求时,返回login.html页面,
        # 页面中{% url'login_page' %}会被反向解析成路径:/login/
        return render(request,'login.html')

    # 当浏览器为post请求时,可以从request.POST中取出请求体数据
    name = request.POST.get('name')
    pwd = request.POST.get('pwd')
    if name == 'cecilia' and pwd == '123':

        # reverse会将别名index_page反向解析为路径/index/
        url = reverse('index_page')
        # 重定向到/index/
        return redirect(url)
    
    else:
        return HttpResponse('用户名密码错误!')

   
def index(request):
    return render(request,'index.html')
# login.html页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<!--login_page必须要加引号-->
    <form action="{% url 'login_page' %}" method="post">
        {% csrf_token %} <!--强调这一行必须要加,后续会说明-->
        <p>用户名:<input type="text" name="name"></p>
        <p>密码:<input type="password" name="pwd"></p>
        <p>提交:<input type="submit" value="提交"></p>
    </form>
</body>
</html>
# index.html页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h3>我是index页面</h3>
</body>
</html>

test:

# 先启动django项目server端----命令行 
python manage.py runserver 8001

1. 在浏览器输入:Http://127.0.0.1:8001/login 
   # 会看到登录页面,输入正确的用户名密码会跳转到index.html
2.当我们修改路由表中匹配路径的正则表达式时,程序其他部分都不用修改

to sum up:

在views.py视图函数文件中,反向解析的使用:
    url = reverse('index_page')
在login.html文件中,反向解析的使用
    {% url 'login_page'%}

Reading: if the direction of path exists using the packet analysis

# urls.py路由文件

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/',admin.site.urls),
    url(r'^article/(\d+)/$',view.article,name='article_page'),#无名分组
    url(r'^user/(?p<uid>\d+)/$',view.article,name='user_page'),#有名分组
]
# 1. 针对无名分组,比如我们要反向解析处:/article/1/这种路径,写法如下
在views.py中,反向解析的使用
url =  reverse('article_page',args=(1,))
在模板login.html文件中,反向解析的使用
{% url 'article_page' 1 %}


# 2.针对有名分组,比如我们要反向解析出:/user/1 这种路径,写法如下
在view.py中,反向解析的使用
方式一: url =  reverse('article_page',args=(1,))
方式二: url =  reverse('user_page',kwargs={'uid':1})
在模板login.html文件中,反向解析的使用
方式一:{% url 'article_page' 1 %}
方式二:{% url 'user_page' uid=1 %}


总结:无名分组和有名分组的反向解析,只要记一种就行了。

Sixth, the namespace

When our project to create multiple app, and under each app have played for alias path match, if there are duplicate alias, then it will return covering occurs when parsing, as follows

6.1 create two app

# 新建项目mysite2---此处用命令行命令创建
# 切换到存储项目的目录下
django-admin startproject mysite2

# 切换到新建的项目下
# 创建两个app项目(app01和app02)
python3 startapp app01
python3 startapp app02

Note here that the following three points:

  1. I used the command line to create a django project, you need to manually create your own Templates .html file folder to store the need to use
  2. And to the settings of TEMPLATES configuration: 'DIRS': [os.path.join ( BASE_DIR, 'templates')]
  3. In the settings INSTALLED_APPS are arranged to 'app01' 'app02'

6.2 manually created in the app store in their routing urls.py

urls.py routing table file 1. app01 under

from django.conf.urls import url
# 导入app01 的views
from app01 import views

urlpatterns = [
    # 为匹配的路径app01/index/起别名’index_page‘
    url(r'^index/$',views.index,name='index_page'),
]

urls.py routing file under 2.app02

from django.conf.urls import url
# 导入app02 的views
from app02 import views

urlpatterns = [
    # 为匹配的路径app02/index/起别名’index_page‘,与app01中的别名相同
    url(r'^index/$',views.index,name='index_page'),
]

6.3 views.py prepared in view of the function of each app

In view function CKS alias 'index_page' do the reverse analysis

views.py view function in the file 1. app01

from django.shortcuts import reverse
from django.shortcuts import render
from django.shortcuts import HttpResponse

def index(request):
    url = reverse('index_page')
    return HttpResponse('我是app01下的index页面。。。,反向解析结果为%s' %url)

views.py view function files under app02

from django.shortcuts import reverse
from django.shortcuts import render
from django.shortcuts import HttpResponse

def index(request):
    url = reverse('index_page')
    return HttpResponse('我是app02下的index页面。。。,反向解析结果为%s' %url)

Routing Table 6.4 Total mysite2 folder urls.py

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    # 因为功能太多,所以在总的路由表中,做路由分发,分发给各个app功能应用
    # 新增的两条路由,注意不能以$结尾
    # include函数就是做分发操作的,当浏览器输入http://127.0.0.1:8001/app01/index时
    # 会先进入到总路由表中进行匹配,正则表达式r'^app01/'会先匹配成功路径app01/
    # 然后include功能函数就会去app01下的urls.py中继续匹配剩余的路径部分
    url(r'app01/',include('app01.urls')),
    url(r'app02/',include('app02.urls'))
]

6.5 Test :( coverage issues)

# 先启动项目server端---命令行式:python manage.py runserver 8001
1.在浏览器中输入:Http://127.0.0.1:8001/app01/index/ 
  会看到我是app02下的index页面。。。,反向解析的结果为/app02/index/

2.在浏览器中输入:Http://127.0.0.1:8001/app02/index/ 
  会看到我是app02下的index页面。。。,反向解析的结果为/app02/index/

In testing, we found that as the input on your browser: Http: //127.0.0.1:8001/app01/index/ or

Http: //127.0.0.1:8001/app02/index/ for alias 'index_page' direction are the result of the analysis / app02 / index /, covering the analytical app01 alias.

6.6 Solution

Solution: is to avoid using the same alias, if you wanted to use the same alias, it would need to use the concept of namespaces in a django, the alias into different namespaces, so even duplicate, not each other conflict, specifically, the following

  1. Total (mysite2 under) urls.py In doing route distribution, specify the name space

    from django.conf.urls import url,include
    from django.contrib import admin
    
    # 总路由表
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    
        # 传给include功能一个元组,元组的第一个值是路由分发的地址
        # 第二个值是我们为名称空间起的名字
        url(r'^app01/',include(('app01.urls','app01'))),
        url(r'^app02/',include(('app02.urls','app02')))
    ]
  2. Views.py under each app modified in view of function for different namespaces respectively anonymous 'index_page' do the reverse analysis

    view.py view function under app01

    from django.shortcuts import reverse
    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    
    def index(request):
        # 解析的是名称空间app01下的别名’index_page‘
        url = reverse('app01:ndex_page')
        return HttpResponse('我是app01下的index页面。。。,反向解析结果为%s' %url)

    view.py view function under app02

    from django.shortcuts import reverse
    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    
    def index(request):
        # 解析的是app02下的名称空间的别名’index_page‘
        url = reverse('app02:index_page')
        return HttpResponse('我是app02下的index页面。。。,反向解析结果为%s' %url)

6.7 test (test to solve the problem)

python manage.py runserver 8001

Browser enter: Http: //127.0.0.1: 8001 / app01 / index / reverse result of the analysis / app01 / index /

Browser enter: Http://127.0.0.1:8001/app02/index/ the results of the reverse analysis is / app02 / index /

6.8 + supplementary summary

1. 在视图函数中基于名称空间的反向解析,用法如下
url = reverse('名称空间的名字:待解析的别名')

2.在模板里基于名称空间的反向解析,用法如下
{% url '名称空间的名字:待解析的别名'%}

Seven, Django2.0 version re_path and path

7.1 re_path

Django 2.0 in re_path the url Django 1.0, like, passed in the first argument is a regular expression

from django.urls import re_path # django 2.0 中的re_path
from django.conf.urls import url # 在django2.0中同样可以导入1.0中的url

urlpatterns = [
    # 用法完全一致
    url(r'^app01/',include(('app01.urls','app01'))),
    re_path(r'^app02/',include(('app02.urls','app02'))),
]

7.2 path

In Django 2.0 There is a new path function, to solve: Data type conversion and redundant regular expressions, as follows

# urls.py 文件

from django.urls import re+path
from app01 import views

urlpatterns = [
    # 问题一:数据类型转换
    # 正则表达式会将请求路径中的年份匹配成功然后以str类型传递函数year_archive
    # 在函数year_archive中如果想要以int类型的格式处理年份,则必须进行数据类型转换
    
    re_path(r'^articles/(?P<year>[0-9]{4})/$',views.year_archive),
    
   
    # 问题二:正则表达式冗余
    # 下述三个路由中匹配article_id 采用了同样的正则表达式,重发编写了三遍,存在冗余问题,并且极不容易管理,因为以但articles_id规则需要改变,则必须同时修改三处的代码
    re_path(r'^articles/(?P<article_id>[a-zA-z0-9]+)/detail/$',view,detail_view),
    re_path(r'^articles/(?P<article_id>[a-zA-z0-9]+)/edit/$',view,edit_view),
    re_path(r'^articles/(?P<article_id>[a-zA-z0-9]+)/delete/$',view,delete_view),
]
# views.py视图文件
from django.shortcuts import render,HttpResponse

def year_archive(request,year):
    print(year,type(year))
    return HttpResponse('year_archive page')

def detail_view(request,article_id):
    print(article_id,type(article_id))
    return HttpResponse('detail_view page')

def edit_view(request,article_id):
    print(article_id,type(article_id))
    return HttpResponse('edit_view page')

def delete_view(request,article_id):
    print(article_id,type(article_id))
    return HttpResponse('delete_view page')

How django2.0 the path to solve these two problems? See example

# urls.py路由文件

from django.urls import re+path
from app01 import views

urlpatterns = [
    # 问题一的结局方案
    path('^articles/<int:year>/',views.year_archive),
    # <int:year>相当于一个有名分组,其中int是django提供的转换器
    # 相当于正则表达式,专门用于匹配数字类型
    # 而year则是我们为有名分组名的名,并且int会将匹配成功后的结果转换位整型后按照格式(year=整型值),传给函数year_archive
    
   
    # 问题二的解决办法
    # 用一个int转换器可以替代对出正则表达式
    path('^articles/<int:article_id>/detail/',view,detail_view),
    path('^articles/<int:article_id>edit/',view,edit_view),
    path('^articles/<int:article_id>delete/',view,delete_view),
]

Emphasize:

  1. or with re_path path different from the url is 1.0, the first parameter to the path is not a regular expression, but an exact match of the path, the first parameter is the same as stated in the preamble of matching characters do not add slash
  2. Angle brackets (<>) captured from the url value, corresponding to known packet
  3. <> May comprise a type converter (converter type), such as the use <int: name> converters used int. If no conversion will match any string, including of course / character

django: default support 5 converter (Path converters)

str:匹配处理路径分隔符(/)之外的非空字符串,这是默认的形式
int:匹配正整数,包含0
slug:匹配字母,数字及斜杠、下划线组成的字符串
uuid:匹配格式化的uuid,如075194d3-6885-417e-a8a8-6c931e272f00 
path:匹配任何非空字符串,包含路径分隔符(/)(不能用?)    

Guess you like

Origin www.cnblogs.com/XuChengNotes/p/11722941.html