Django2.x

路由配置

  • 主路由配置

    • setting.py 中 ROOT_URLCONF 指定了主路由配置列表 urlpatterns 的文件位置

      • 例如:ROOT_URLCONF = 'MyDjango.urls'
      • 指定主路由配置列表 urlpatterns 文件位置在 MyDjango 文件夹下的 urls.py 文件
    • MyDjango 的主路由配置 urls.py 文件
      - path() 函数参数:
      - route: 字符串类型,匹配的请求路径
      - views: 指定路径所对应的视图处理函数名称,不要带()
      - name: 为地址起别名,在模板中地址反向解析

      # MyDjango/urls.py 主路由文件
      from django.contrib import admin    # 导入admin功能模块
      from django.urls import path, include   # 导入URL编写模块
      
      # 整个项目的URL集合,每个元素代表一条URL信息
      urlpatterns = [
      # 设定admin的URL。'admin/' 代表127.0.0.1:8000/admin 地址信息,admin后面的斜杠是路径分隔符;
      # admin.site.urls 是URL的处理函数,也成为了视图函数
      path('admin/', admin.site.urls),
      # URL为空,代表为网站的域名,即 127.0.0.1:8000,通常是网站的首页
      # include将该URL分发给index的urls.py处理
      path('', include('index.urls')),
      path('', include('bookstore.urls')),
      path('', include('lx_url.urls')),
      ]
      
  • 路由配置 - path - 转换器

    转换器类型 作用 样例
    str 匹配除了'/'之外的费控字符串 "v1/users/str:username"匹配/v1/users/root
    int 匹配0或任何正整数。返回一个int "page/int:page"匹配/page/100
    slug 匹配任意由ASCII字母或数字以及连字符和下划线组成的段标签 "detail/slug:sl"匹配/detail/this-is-django
    path 匹配非空字段,包括路径分隔符'/' "v1/users/path:ph"匹配/v1/users/a/b/c
    • re_path: 使用正则表达式匹配url
      • ?P: 固定格式
      • : 变量命名的编写规则
      • [0-9]{1,2}: 正则表达式的匹配模式, 代表变量的长度为1或2, 只允许取0-9的值
      • 浏览器访问: http://127.0.0.1:8000/operation/{num1}}/{op}}/{num2}, num1和num2为1或2位正整数才会分发到re_path路由,否则会分发到path路由
      # app路由:lx_url/urls.py 文件
      from django.urls import path, re_path
      from . import views
      
      urlpatterns = [
      	re_path(r'operation/(?P<num1>[0-9]{1,2})/(?P<op>w+)/(?P<num2>[0-9]{1,2})$', views.re_operation),
      	path('operation/<int:num1>/<str:op>/<int:num2>', views.operation),
      ]
      
      
      # app视图: lx_url/views.py
      from django.http import HttpResponse
      from django.shortcuts import render
      
      # Create your views here.
      def operation(request, num1, operator, num2):
          '''
          视图函数
          :param request: 视图函数必需参数
          :param num1: urls.py 中传入的参数, 用来计算的正整数
          :param operator: urls.py 中传入的参数, 用来计算的运算符, add: 加法, sub: 减法, mul: 乘法
          :param num2: urls.py 中传入的参数, 用来计算的正整数
          :return:
          '''
          if operator == 'add':
              cal_operator = '+'
          elif operator == 'sub':
          	cal_operator = '-'
          elif operator == 'mul':
          	cal_operator = '*'
          else:
          	return HttpResponse(f'运算符错误! 选择的运算符: {operator}不是add、sub、mul')
      
      	result = eval(f"{num1} {cal_operator} {num2}")
      	return HttpResponse(f'{num1} {cal_operator} {num2} = {result}')
      
      def re_operation(request, num1, op, num2):
          '''
          视图函数
          :param request: 视图函数必需参数
          :param num1: urls.py 中传入的参数, 用来计算的正整数
          :param op: urls.py 中传入的参数, 用来计算的运算符, add: 加法, sub: 减法, mul: 乘法
          :param num2: urls.py 中传入的参数, 用来计算的正整数
          :return:
          '''
          if op == 'add':
          	cal_operator = '+'
          elif op == 'sub':
          	cal_operator = '-'
          elif op == 'mul':
          	cal_operator = '*'
          else:
          	return HttpResponse(f're_path 运算符错误! 选择的运算符: {op}不是add、sub、mul')
      
          result = eval(f"{num1} {cal_operator} {num2}")
          return HttpResponse(f're_path: {num1} {cal_operator} {num2} = {result}')
      

URL的反向解析

  • URL的绝对地址和相对地址

    • 绝对地址: http://127.0.0.1/8000/index, ip + port + 地址
    • 相对地址:
      • 带斜杠的相对地址: 不论是在哪个地址请求的,请求后都会变成这个 http://ip:port/url
        • 如: /page, 拼接为: http://ip:port/page, 不论是在哪个地址请求的,请求后都会变成拼接后url
      • 不带斜杠的相对地址: 在当前访问的URL后, 将设置的相对地址拼接到后面
  • URL反向解析

    • URL反向解析是指在视图或模板中,用 path 定义的名称来动态查找或计算出响应的路由

    • path 函数语法:

      • path(route, views, name='别名')
      • path('page', views.page_view, name='page_url')
    • 根据 path 中 name 关键字传参给URL确定了一个唯一确定的名字, 在模板或视图中, 可以通过这个名字反向推断出此URL信息

    • 在模板中 - 通过url标签实现地址的反向解析

      • 不带参数的URL: {% url '别名' %}
      • 带参数的URL: 不论是字符串还是数字, 在模板中都要使用字符串的方式
        • 位置传参: {% url '别名' '位置参数1' '位置参数2' %}
        • 关键字传参: {% url '别名' name='xx' age='10' %}
    # app 中的 urls.py
    from django.urls import path, re_path
    from . import views
    
    urlpatterns = [
        path('test_url', views.test_url, name='tr'),
        path('base_index', views.base_view, name='base_index'),
    ]
    
    # app 中的 views.py
    from django.template import loader
    from django.http import HttpResponse, HttpResponseRedirect
    from django.shortcuts import render
    
    def test_url(request):
        return render(request, 'test_url.html')
    
    def base_view(request):
        return render(request, 'base.html')
    
    # app 中的templates/test_url.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>EST URL</title>
    </head>
    <body>
    	<a href="{% url 'base_index' %}">这是反向解析的url</a>
    </body>
    </html>
    
    • 在视图函数中, 可以调用Django中的 reverse 方法进行反向解析
      • 语法:
        • from django.urls import reverse
        • reverse('别名', args=[], kwargs=[])
    # app 中的 urls.py
    from django.urls import path, re_path
    from . import views
    
    urlpatterns = [
        path('test_url_redirect', views.test_url_redirect, name='trd'),
        path('test_url', views.test_url, name='tr'),
    ]
    	
    # app 中的 views.py
    from django.urls import reverse
    from django.template import loader
    from django.http import HttpResponse, HttpResponseRedirect
    from django.shortcuts import render
    
    def test_url_redirect(request):
        '''重定向反向解析'''
          reverse_url = reverse('tr')
          return HttpResponseRedirect(reverse_url)
    

  • 练习1:
    • 浏览器访问网址:http://127.0.0.1:8000/page/1,页面显示:这是编号为1的网页
    • 浏览器访问网址:http://127.0.0.1:8000/page/2,页面显示:这是编号为2的网页
    • 傻瓜式实现
      # lx_url app路由:lx_url/urls.py 文件
      from django.urls import path, re_path
      
      from . import views
      
      urlpatterns = [
          path('page/1', views.page1_view),
          path('page/2', views.page2_view),
      ]
      
      # lx_url app视图:lx_url/views.py
      from django.http import HttpResponse
      from django.shortcuts import render
      
      # Create your views here.
      def page1_view(request):
          return HttpResponse('这是编号为1的网页')
      
      def page2_view(request):
          return HttpResponse('这是编号为2的网页')
      
    • 以上虽然可以实现,但是如果有100个网页,需要复制100遍;优化代码,使用变量参数的方式实现
    # lx_url app路由:lx_url/urls.py 文件
    from django.urls import path, re_path
        
    from . import views
        
    urlpatterns = [
        # <int:page>: <参数数据类型:参数变量名>
        path('page/<int:pg>', views.page_view),
    ]
        
    # lx_url app视图:lx_url/views.py
    from django.http import HttpResponse
    from django.shortcuts import render
        
    # Create your views here.
    def page_view(request, pg):
        '''
        视图函数
        :param request: 视图函数必需参数
        :param pg: urls.py 中传入的参数
        :return:
        '''
        return HttpResponse(f'这是编号为{pg}的网页')
    

  • 练习2:
    # app路由配置 lx_url/urls.py
    from django.urls import path, re_path
    
    from . import views
    
    urlpatterns = [
        # <int:page>: <参数数据类型:参数变量名>
        path('operation/<int:num1>/<str:operator>/<int:num2>', views.operation),
    ]
    
    # app视图 lx_url/views.py
    from django.http import HttpResponse
    from django.shortcuts import render
    
    # Create your views here.
    def operation(request, num1, operator, num2):
        '''
        视图函数
        :param request: 视图函数必需参数
        :param num1: urls.py 中传入的参数, 用来计算的正整数
        :param operator: urls.py 中传入的参数, 用来计算的运算符, add: 加法, sub: 减法, mul: 乘法
        :param num2: urls.py 中传入的参数, 用来计算的正整数
        :return:
        '''
        if operator == 'add':
      	    cal_operator = '+'
        elif operator == 'sub':
      	    cal_operator = '-'
        elif operator == 'mul':
      	    cal_operator = '*'
        else:
    	    return HttpResponse(f'运算符错误! 选择的运算符: {operator}不是add、sub、mul')
    
        result = eval(f"{num1} {cal_operator} {num2}")
        return HttpResponse(f'{num1} {cal_operator} {num2} = {result}')
    

  • re_path 练习3:
    # app的路由: lx_url/urls.py
    from django.urls import path, re_path
    from . import views
    
    urlpatterns = [
        re_path(r'birthday/(?P<num1>[0-9]{4})/(?P<num2>[0-9]{1,2})/(?P<num3>[0-9]{1,2})$', views.re_librthday),
        re_path(r'birthday/(?P<num1>[0-9]{1,2})/(?P<num2>[0-9]{1,2})/(?P<num3>[0-9]{4})$', views.re_librthday),
    ]
    
    # app的视图: lx_url/views.py
    from django.http import HttpResponse
    from django.shortcuts import render
    
    def re_librthday(request, year, month, day):
      year = int(year)
      month = int(month)
      day = int(day)
    
    if month > 0 and month < 13:
        if month in (1, 3, 5, 7, 8, 10, 12) and day > 0 and day < 32:
    	    result = f'生日为:  {year}年{month}月{day}日'
    
        elif month in (4, 6, 9, 11)  and day > 0 and day < 31:
    	    result = f'生日为:  {year}年{month}月{day}日'
    
        elif month == 2 and day > 0 and day < 30:
    	    result = f'生日为:  {year}年{month}月{day}日'
    
        else:
    	    result = f'day 错误! year: {month}, month: {year}, day: {day}'
    
    else:
        result = f'month 错误, month 不是1到12之间的正整数! month: {year}'
    
      return HttpResponse(result)
    
原文地址:https://www.cnblogs.com/gxfaxe/p/15017420.html