在第一章的基础上:

2.2 路由转换器

1、进入虚拟环境,在虚拟环境同级目录下创建项目chapter02,进入项目安装应用example,代码如下:

django-admin startproject chapter02
python manage.py startapp example

2、在example应用中创建converter.py文件,在这个文件中定义自定义路由转换器。

from django.urls import register_converter
class MyConverter:
    regex ='1[3-9]\d{9}'
    def to_python(self,value):
        return value
    def to_url(self,value):
        return value
register_converter(converter=MyConverter,type_name='mobile')   

3、在example应用中定义视图函数,view.py代码如下:

from django.shortcuts import render
from django.http import HttpResponse
def show_mobile(request,phone_num):
    return HttpResponse(f'手机号码为:{phone_num}')

4、完成视图函数定义后,在根路由中定义访问show_mobile()视图函数的URL模式,并使用自定义路由转换器匹配手机号。

from django.contrib import admin
from django.urls import path
from example.converter import MyConverter
from example import views
urlpatterns = [
    path("admin/", admin.site.urls),
    path('mobile/<mobile:phone_num>/',views.show_mobile)
]

5、运行开发服务器:python manage.py runserver

6、浏览器访问:http://127.0.0.1:8000/mobile/13012345678/ 能够在页面中显示呈现手机号。

2.3 使用正则表达式匹配URL

1.设置分组名的正则表达式,在根路由文件下书写:

re_path(r"^articles/(?P<year>[0-9]{4})/(?P<month>[1-9]|1[0-2])/$", views.show_year_month),

2.在views.py文件中配置show_year_month函数:

def show_year_month(request,year,month):
    return HttpResponse(f'{year}{month}月')

3.未设置分组名的正则表达式,在根路由文件下书写:

re_path(r'num/(\d+)/', views.number),

4.在views.py文件中配置show_year_month函数:

def number(request,show_number):
    return HttpResponse(f'数字为:{show_number}')

2.4 路由分发(继承上节课,已经创建项目chapter02和应用users)

1.引入应用urls.py文件,在根路由中使用include函数导入应用user中的urls文件,注意要导入include包

from django.contrib import admin
from django.urls import path,re_path,include
]
urlpatterns = [
    path('admin/', admin.site.urls),
    path('example/',include('example.urls'))
]

2.在应用example中创建urls.py,配置子路由

from django.urls import path
from example import views
urlpatterns = [
    path('login/',views.login),
]

3.编写子路由配置中的函数

from django.http import HttpResponse
def login(request):
    return  HttpResponse(f'这是login函数!')

1.在根路由中配置额外的url模式列表

from django.contrib import admin
from django.urls import path,include
from example import views
extra_patterns=[
    path('reports/',views.report),
    path('reports/<int:id>/',views.show_num),
]
urlpatterns = [
    path('admin/', admin.site.urls),
    path('example/',include(extra_patterns))

]

2.在视图文件中写视图函数

```python
from django.http import HttpResponse
def report(request):
    return HttpResponse(f'这是一个report函数!')
# 注意这个id参数不能丢
def show_num(request,id):	
    return HttpResponse(f'这是一个show_num函数!')

2.5 向视图函数传递额外参数(继承上节课,已经创建项目chapter02和应用users)

1.在子应用中子路由文件urls.py,再在根路由配置中配置urls.py文件,包含应用中的子路由文件(需要导入include)。

from django.contrib import admin
from django.urls import path,include
from example import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('example.urls')),
]

2.在子路由文件中书写需要传递的参数。

from django.urls import path
from . import views
urlpatterns=[
    path('blog-list/',views.blog,{'blog_id':3})
]

3.配置应用中的视图函数。

from django.http import HttpResponse
def blog(request,blog_id):
    return HttpResponse(f'参数blog_id的值为{blog_id}')

4.往主路由path中配置中的添加参数

from django.contrib import admin
from django.urls import path,include
from example import views
urlpatterns = [
    path('admin/', admin.site.urls),
    # path('mobile/<mobile:phone_num>',views.show_mobile),
    path('',include('example.urls')),
    path('',include('example.urls'),{"name":'django'}),
]

5.子路由相应的添加路径path

from django.urls import path
from . import views
urlpatterns=[
    path('blog-list/',views.blog,{'blog_id':3}),
    path('book/',views.book)
]

6.添加相应的视图函数

from django.http import HttpResponse
def show_mobile(request, phone_num):
    return HttpResponse(f'手机号为:{phone_num}')
def blog(request,blog_id):
    return HttpResponse(f'参数blog_id的值为{blog_id}')
def book(request,name):
    return HttpResponse(f'book-{name}')

7.继续在子路由中添加path

from django.urls import path
from . import views
urlpatterns=[
    path('blog-list/',views.blog,{'blog_id':3}),
    path('book/',views.book),
    path('conlumn/',views.book)
]

8.在视图文件中添加相应的函数

from django.http import HttpResponse

def show_mobile(request, phone_num):
    return HttpResponse(f'手机号为:{phone_num}')

def blog(request,blog_id):
    return HttpResponse(f'参数blog_id的值为{blog_id}')

def book(request,name):
    return HttpResponse(f'book-{name}')

def conlumn(request,name):
    return HttpResponse(f'conlumn-{name}')

2.6.1-2.6.2使用reverse函数反向解析url

1.创建goods应用,在应用中创建子路由urls.py,输入子路由地址

from django.urls import path
from goods import views
urlpatterns = [
    path('url-reverse/', views.get_url, name='url'),
]

2.将子路由添加到根路由中

path('', include('goods.urls')),

3.在应用的视图文件中创建函数get_url

from django.http import HttpResponse
from django.shortcuts import reverse

def get_url(request):
    return HttpResponse(f"反向解析的url为:{reverse('url')}")

2.6.3应用的命名空间

1.在项目中创建应用goods和users,在主路由中添加子路由

path("users/",include('users.urls')),
path('goods/', include('goods.urls')),

2.在各自应用的的views中创建各自的index函数

def index(request):
    return HttpResponse(f"goods应用的反向解析的url为:{reverse('goods:index')}")
def index(request):
    return HttpResponse(f"users应用的反向解析的url为:{reverse('users:index')}")

3.在各自的应用中创建url路由

path('index/', views.index, name='index')
path('index/', views.index, name='index')

4.启动开发服务器访问http://127.0.0.1:8000/users/index/,而页面显示的为“users应用的反向解析的url为/goods/index/”,为了解决这个问题需要在各自的url中添加appname字段。

from django.urls import path
from goods import views
app_name = 'goods'
urlpatterns=[
    path('index/', views.index, name='index'),
]
from django.urls import path
from users import views
app_name = 'users'
urlpatterns = [
    path('index/', views.index, name='index'),
]

2.6.4实例命名空间

1.使用命令:python .\manage.py startapp app01创建应用app01

2.在根路由中创建path模式,两种模式指向同一个文件

path('path-one/', include('app01.urls')),
path('path-two/', include('app01.urls')),

3.在应用app01中创建urls.py文件,并配置自路由

from django.urls import path
from app01 import views
app_name = 'app01'
urlpatterns = [
    path('index/', views.index, name='url-path'),
]

4.编写app01.views视图函数index

from django.http import HttpResponse
from django.shortcuts import reverse
def index(request):
    return HttpResponse(f"当前应用的反向解析的url为:{reverse('app01:url-path')}")

5.访问http://127.0.0.1:8000/path-one/indexhttp://127.0.0.1:8000/path-two/index查看反向解析的模式结果,发现两次解析的结果是一样的,这里就出现问题了,问了解决这一问题引入实例命名空间,具体操作如下:

6.在根路由中的include函数添加namespace,即app01的views文件代码为:

from django.http import HttpResponse
from django.shortcuts import reverse
def index(request):
    return HttpResponse(f"当前应用的反向解析的url为:{reverse('app01:url-path',current_app= request.resolver_match.namespace)}")

7.访问http://127.0.0.1:8000/path-one/indexhttp://127.0.0.1:8000/path-two/index查看反向解析的模式结果。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐