自动化测试平台搭建系列(7)——Django中的路由配置及规则

本文详细介绍了Django中的路由走向,包括path和re_path函数的区别,以及如何通过主子路由进行视图分发,以提高URL管理效率。通过实例演示了如何在不同应用中设置路由和视图函数,帮助读者理解URL配置的组织结构。
摘要由CSDN通过智能技术生成


趁老板不在,上班摸会鱼!!!
主子路由部分对应的码云地址:
主子路由
接着上篇继续写,这篇主要写两部分:视图(views)和路由(urls)

路由走向

首先看下url路由查找,详细了解些路由的工作原理。
借助上篇文章的例子解释一下
先看代码块:
views.py

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


# Create your views here.

def test(request):
    return HttpResponse('this is a test demo!')

urls.py

from django.contrib import admin
from django.urls import path

from users import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('test', views.test),
]

启动服务后,在输入网址:127.0.0.1:8000/test可访问以下页面
在这里插入图片描述
继续看http://127.0.0.1:8000/test
解析它的走向:
只要有请求就会有一个请求对象,它也不例外,它的请求对象是request
有请求对象接下来就会进到urls.py(路由配置表)文件中,路由配置表urls.py中有个urlpatterns,它是一个列表。
只要是发过来请求,我知道请求的路径后,就会去urls.py的urlpatterns中去找。这里我请求的是“test”,那就会去urlpatterns中去找我的这个test有没有定义,如果有定义接下来就会去找它所匹配的视图函数。
也就是说127.0.0.1:8000/test中的test会去urlpatterns中查找test,而我正好也定义了path(‘test’, views.test),,所以他能找到,而path(‘test’, views.test),中的test指向了后面views.test中的test函数,views是我提前就导入好的

from users import views

所以接下的动作就是去users里面的views.py里去找test函数
也就是刚才定义的视图函数

def test(request):
    return HttpResponse('this is a test demo!')

这个时候其实我的request对象已经产生了,就是127.0.0.1:8000
它会把这个作为参数传给def test(request)
然后会响应this is a test demo!给浏览器展示给用户
简略的画个图来理解一下:
在这里插入图片描述

主子路由

在哪里定义路由?
在urls.py中定义路由
路由是一个列表,格式如下:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index),
    path('test', views.test),
]
urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
    path('<int:question_id>/results/', views.results, name='results'),
    path('<int:question_id>/vote/', views.vote, name='vote'),
]

例:
展示不同的文章
views.py

# -*- coding:utf-8 -*-
articale = ['文章1', '文章2', '文章3', '文章4', '文章5', '文章6', '文章7']

def show_article(request, num):
    # 因为索引都是从0开始的,所以我用了num-1,也可以直接num
    return HttpResponse(articale[num - 1])

urls.py

from django.contrib import admin
from django.urls import path

from users import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('article/<int:num>', views.show_article)
]

在这里插入图片描述
在这里插入图片描述
用名字展示:
views.py

# -*- coding:utf-8 -*-

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

# Create your views here.

def show_article_byname(request, name):
    return HttpResponse('文章:' + name)

urls.py

from django.contrib import admin
from django.urls import path

from users import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('article/<str:name>',views.show_article_byname),
]

在这里插入图片描述
在这里插入图片描述

path函数:

首先看下path函数的底层

"""Functions for use in URLsconfs."""
from functools import partial
from importlib import import_module

from django.core.exceptions import ImproperlyConfigured

from .resolvers import (
    LocalePrefixPattern, RegexPattern, RoutePattern, URLPattern, URLResolver,
)


def include(arg, namespace=None):
    app_name = None
    if isinstance(arg, tuple):
        # Callable returning a namespace hint.
        try:
            urlconf_module, app_name = arg
        except ValueError:
            if namespace:
                raise ImproperlyConfigured(
                    'Cannot override the namespace for a dynamic module that '
                    'provides a namespace.'
                )
            raise ImproperlyConfigured(
                'Passing a %d-tuple to include() is not supported. Pass a '
                '2-tuple containing the list of patterns and app_name, and '
                'provide the namespace argument to include() instead.' % len(arg)
            )
    else:
        # No namespace hint - use manually provided namespace.
        urlconf_module = arg

    if isinstance(urlconf_module, str):
        urlconf_module = import_module(urlconf_module)
    patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
    app_name = getattr(urlconf_module, 'app_name', app_name)
    if namespace and not app_name:
        raise ImproperlyConfigured(
            'Specifying a namespace in include() without providing an app_name '
            'is not supported. Set the app_name attribute in the included '
            'module, or pass a 2-tuple containing the list of patterns and '
            'app_name instead.',
        )
    namespace = namespace or app_name
    # Make sure the patterns can be iterated through (without this, some
    # testcases will break).
    if isinstance(patterns, (list, tuple)):
        for url_pattern in patterns:
            pattern = getattr(url_pattern, 'pattern', None)
            if isinstance(pattern, LocalePrefixPattern):
                raise ImproperlyConfigured(
                    'Using i18n_patterns in an included URLconf is not allowed.'
                )
    return (urlconf_module, app_name, namespace)


def _path(route, view, kwargs=None, name=None, Pattern=None):
    if isinstance(view, (list, tuple)):
        # For include(...) processing.
        pattern = Pattern(route, is_endpoint=False)
        urlconf_module, app_name, namespace = view
        return URLResolver(
            pattern,
            urlconf_module,
            kwargs,
            app_name=app_name,
            namespace=namespace,
        )
    elif callable(view):
        pattern = Pattern(route, name=name, is_endpoint=True)
        return URLPattern(pattern, view, kwargs, name)
    else:
        raise TypeError('view must be a callable or a list/tuple in the case of include().')


path = partial(_path, Pattern=RoutePattern)
re_path = partial(_path, Pattern=RegexPattern)

看最后两段代码:

path = partial(_path, Pattern=RoutePattern)
re_path = partial(_path, Pattern=RegexPattern)

这里path函数其实用的是偏函数(partial)
真正是其实是由_path这个函数来完成的
在这里插入图片描述
接着看这个函数:

def _path(route, view, kwargs=None, name=None, Pattern=None):

这里有两项是必填的,即route和view,剩下的三项选填
所以path函数有两项是必填的,也就是route(路由)和view(视图函数)
只要用到path,第一个就要定义路由名,然后就是这个路由绑定的函数

那么接下来第二个问题来了,视图函数从哪里找呢?
1、新建APP
2、新建的APP里面包含了一个叫做views.py的文件
3、在这个view.py文件里去定义视图函数

re_path函数

re_path函数是一个支持正则的函数
其实re_path和path用的都是_path这个函数,只不过re_path支持正则,它的Pattern变了
参数:
route:路由(支持正则表达式)
view:视图函数

re_path = partial(_path, Pattern=RegexPattern)

语法:

re_path(r'路由名称/正则表达式',绑定视图路径)

一般使用path的比较多,除非path不能支持了,需要正则支持,会用到re_path

路由分发

建APP时,除了users之后还有一个goods,如果想展示商品(goods)该怎么处理呢?
按常规思想应该是:首先需要在goods里面创建视图(views.py),然后再在urls.py里定义商品路由
这样是可行的,但是如果后面有很多app,每个APP又有N多个视图函数,也就意味着我的路由文件里(urls.py)要写一大坨的路由,其中会包含用户信息类的,商品类的,以及后面各种其他类的,这样找起来就显得异常的杂乱。
为了应对这个问题就需要用到主子路由的分发了
也就是主路由定义主干线
用子路由定义我自己的路由部分
接下来就看下如何走主子路由
首先看下主路由是谁,主路由就是urls.py文件,在主路由里面定义主干道
子路由需要自己去做,在每个新建的app里面新建一个urls.py文件
在这里插入图片描述

在这里插入图片描述
把原始的urls.py文件里的内容复制到这新建的urls.py文件中
也就是下面这堆代码:


urlpatterns = [
    
]

在这里插入图片描述
接下来来如何与主路由建立联系
这个时候需要在主路由里创建与子路由的关联
主路由urls.py

# 1. Import the include() function: from django.urls import include, path
# 2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
from django.contrib import admin
from django.urls import path, include

from users import views

urlpatterns = [
    path('admin/', admin.site.urls),
    #其中“/”表示它还有下一层级
    #include代表引入对应路径
    path('users/',include('users.urls')),
    path('goods/',include('goods.urls')),
]

在这里插入图片描述
这个时候主路由与子路由的关系设置好了,接下来就是如何去展示我的APP视图内容,这时候就需要对子路由(APP内的urls.py做设置了)
这里先以users的首页函数(index)为例
代码如下

from django.urls import path

from users.views import index

urlpatterns = [
    path('', index),
]

在这里插入图片描述
在这里插入图片描述
这里先实验一波,启动项目
因为是在users目录下,所以输入/users,在后面什么都不跟的情况下会默认找到我的hello world!
在这里插入图片描述
下面继续(其实和之前的路由写法一样!)
直接上代码

from django.urls import path

from users.views import index, test

urlpatterns = [
    path('', index),
    path('test', test)
]

在这里插入图片描述
这里我访问的是http://127.0.0.1:8000/users/test
也就代表是users相关的东西
goods和其他的APP也同理
接下来再写一个例子
goods的商品列表展示:
views.py视图部分:

# -*- coding:utf-8 -*-

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

# Create your views here.
goods = ['苹果', '香蕉', '西瓜', '芒果']


def show_goods(request):
    s = "便利蜂商品有:<br>"
    for g in goods:
        s = s + g + '<br>'
    return HttpResponse(s)

子路由urls.py部分:

from django.urls import path

from goods.views import index, show_goods

urlpatterns = [
    path('', index),
    path('all',show_goods)
]

这时候看一下执行结果:
在这里插入图片描述
这里主要看下路由部分

path('all',show_goods)

这里路由会去根据all寻找他的路径也就是show_goods函数,说明http://127.0.0.1:8000/goods/all里的这个goods只是一个主子路由的分发依据

子路由的创建方法:
1、新建APP
2、进入APP中,新建urls.py文件
3、在新建的urls.py文件中添加路由
更新中。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十七光年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值