zoukankan      html  css  js  c++  java
  • django框架之路由层 视图层......

    Django 框架结构

    urlspy    路由层
    views.py  视图层
    templates   模板层
    models.py   模型层

     

    路由层

    数据处理结果request,是由wsgiref完成

    1. 路由匹配

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^$', views.home),  # 网站首页路由
        url(r'test/$', views.test),  # 以test/结尾
        url(r'testadd/$', views.testadd),  # 以testadd/结尾
        url(r'', views.error)   # 网站不存在页面,该路由存在,网页将不会自动加/重定向
    ]

    url('正则表达式',“视图函数内存地址”)

    url(r'^index.html',views.index)

    url(r'^index/d+.html',views.index)
    url(r'^index/[0-9]{4}/',views.index)

    第一个参数是正则表达式,匹配规则按照从上往下依次匹配,匹配到一个后立即执行对应的函数,不再继续往下匹配

    路由过多的时候,可能在它之前就有路由匹配上,目标函数将不会被执行,一可以换前后位置,二换新的路由

    PS:路由匹配到的数据默认都是字符串形式

     

    1)分组

    无名分组:将加括号的正则表达式匹配到的内容,当做位置参数自动传递给对应的视图函数
    有名分组:将加括号的正则表达式匹配到的内容,当做关键字参数自动传递给对应的视图函数

    注意:无名分组和有名分组不支持混合使用!!!

      但是支持用一类型多个分组匹配

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
      url(r'^admin/([0-9]{4})/', admin.site.urls),  # 无名分组, url(r
    '^test/d+/', views.test), # 匹配一个或多个数字,只要有数字访问不受影响 url(r'^test/(d+)/', views.test1), # 无名分组,会将d+当做位置参数传递给函数 url(r'^test/(d+)/(d+)/', views.test11), # 无名分组多个 url(r'^test/(?P<year>d+)/', views.test2), # 有名分组,会将d+当做关键字参数传递给函数 url(r'^test/(?P<year>d+)/(?P<xx>d+)/', views.test22) # 有名分组多个 ]
    def test(request):
        return HttpResponse('test')
    
    
    def test1(request, xx):
        print(xx)
        return HttpResponse('test1')
    
    
    def test11(request, xx, yy):  # 形参可以任意表示,但数量相等
        print(xx)
        print(yy)
        return HttpResponse('test11')
    
    
    def test2(request, year):
        print(year)
        return HttpResponse('test2')
    
    
    def test22(request, xx, year):  # 形参必须与路由相同,位置任意
        print('xx:', xx)
        print('year:', year)
        return HttpResponse('test22')

    2)反向解析

    视图层根据名字动态获取该别名所对应的能够匹配url的路径 from django.shortcuts import reverse

    可以给每一个路由与视图函数对应关系起一个别名
    这个名字能够唯一标识出对应的路径
    注意:这个名字不能重复是唯一的 

    本质:获取到能够访问名字所对应的视图函数

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/$', views.index, name='index'),  # 路由与视图函数的关系取别名 index
        url(r'^index1/$', views.index1, name='index1'),  # 别名 index1
        url(r'^test3/(d+)/', views.test3, name='test3'),  # 别名 test3
       url(r'^test4/(d+)/(d+)/(d+)/', views.test4, name='test4'), # 别名 test4
    ]
    from django.shortcuts import render,HttpResponse,reverse
    
    
    def index(request):
        print('url:', reverse('index'))
        return render(request, 'index.html')
    
    
    def index1(request):
        print(reverse('test3', args=(1,)))  # test3 需要一个无名分组参数,不传参报错
        return render(request, 'index1.html')
    
    
    def test3(request, xx):
        print('xx:', xx)
        print('url:', reverse('index1'))
        return HttpResponse('test3')
    def test4(request, *args):     
      print(reverse('test4', args=args)) # /test4/599/288/246/
      return HttpResponse(*args) # 599 ??
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    <a href="{% url 'index' %}"></a>
    
    
    </body>
    </html>
    index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    <a href="{% url 'test3' 10 %}"></a>
    <a href="{% url 'test3' 10 %}"></a>
    <a href="{% url 'test3' 10 %}"></a>
    <a href="{% url 'test3' 10 %}"></a>
    <a href="{% url 'test3' 10 %}"></a>
    <a href="{% url 'index1' %}"></a>
    <a href="{% url 'index1' %}"></a>
    <a href="{% url 'index1' %}"></a>
    <a href="{% url 'index1' %}"></a>
    
    </body>
    </html>
    index1.html
    # 反向解析(根据名字动态获取到对应路径)
        url(r'^index6668888/$',views.index,name='index')
    前端使用
        {% url '别名' %}
    后端使用
        from django.shortcuts import reverse
        reverse('index')
    
    # 无名分组反向解析
        url(r'^test/(d+)/',views.test,name='list')
    后端使用
        reverse('list',args=(10,))
    前端使用
        {% url 'list' user_obj.pk %}
    
    # 有名分组反向解析
    后端使用
        reverse('list',args=(10,))    # 后端有名分组和无名分组都可以用这种形式
        reverse('list',kwargs={'year':10})    # 下面这个了解即可
    前端使用
        {% url 'list' user_obj.pk %}    # 前端有名分组和无名分组都可以用这种形式
        {% url 'list' xxx=user_obj.pk %} # 下面这个了解即可  


    # 总结:针对有名分组与无名分组的反向解析统一采用一种格式即可
      后端 reverse(
    'list',args=(10,)) # 这里的数字通常都是数据的主键值
      前端 {
    % url 'list' user_obj.pk %}

    实例

    展示数据:
    user_list = models.User.objects.all()
    
    url(r'^edit/(d+)', views.edit, name='edit')
    前端模板语法
         {% for user_obj in user_list %}
            <a href='edit/{{ user_obj.pk }}/'></a>
    {% endfor %}
    增加编辑按钮: 视图函数
    from django.shortcuts import reverse def edit(request, edit_id): url = reverse('edit', args=(edit_id,)) 模板 {% url 'edit' edit_id %}


    3)路由分发

    django每一个app下面都可以有自己的urls.py路由层,templates文件夹,static静态文件夹
    项目名下urls.py(总路由)不再做路由与视图函数的匹配工作,而是做一个中转

    项目名下urls.py:路由分发千万不要$结尾

    from django.conf.urls import include
    from app01 import urls as app01_urls 
    from app02 import urls as app02_urls
    url(r
    '^app01/', include(app01_urls)),
    url(r'^app02/', include(app02_urls)),
    url(r'^app03/', include('app03.urls'))

    在应用下新建urls.py文件,在该文件内写路由与视图函数的对应关系即可

    from django.conf.urls import url
    from app01 import views
    
    urlpatterns = [
        url(r'^index/', views.index)
    ]

    4)名称空间

    当多个app中给路由与视图起别名重名的情况,使用名称空间避免反向解析不准的情况

    不使用名称空间,可以在起别名的时候加上一些具有唯一标识的前缀

    项目urls.py
    url(r'^app01/',include(app01_urls,namespace='app01')),
    url(r'^app02/',include(app02_urls,namespace='app02'))
    
    app01.urls.py
        from django.conf.urls import url
        from app01 import views
        urlpatterns = [
            url(r'^index/',views.index,name='index')
        ]
    
    app02.urls.py
        from django.conf.urls import url
        from app02 import views
        urlpatterns = [
            url(r'^index/',views.index,name='index')
        ]
    
    app01.views.py
    reverse('app01:index')
    
    app02.views.py
    reverse('app02:index')

    5)伪静态网页

    搜索优化seo:Search Engine Optimization,利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名

    url(r'^index.html',views.index,name='app01_index')
    url(r'^index/d+.html',views.index,name='app01_index')

    6)虚拟环境

    每一个项目都有属于自己的python环境,避免导入多余的模块造成资源的浪费;

    不同的项目配置不同的python解释器,配置需要用到的模块、版本

    7)django1.0与django2.0

    区别1:django2.0里面的path第一个参数不支持正则,你写什么就匹配,100%精准匹配

    区别2:django2.0里面的re_path对应着django1.0里面的url

    虽然django2.0里面的path不支持正则表达式,但是它提供五个默认的转换器

    str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式

    int,匹配正整数,包含0。

    slug,匹配字母、数字以及横杠、下划线组成的字符串。

    uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。

    path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)

    自定义转换器:

    1.正则表达式

    2.类 :写两个方法 to_python & to_url

    3.注册:起一个名字

    url(r'^index/<str:id>',views.index) 
    url(r'^index/<xxx:id>',views.index)


    from
    django.urls import register_converter # 自定义转换器 class FourDigitYearConverter: regex = '[0-9]{4}' def to_python(self, value): return int(value) def to_url(self, value): return '%04d' % value # 占四位,不够用0填满,超了则就按超了的位数来! register_converter(FourDigitYearConverter, 'yyyy')

    视图层

    1. FBV与CBV

    后端业务逻辑FBV与CBV完成

    FBV:function base views,在视图里使用函数处理请求

    CBV:class base views,在视图里使用类处理请求

    无论是FBV还是CBV,路由层都是路由对应视图函数内存地址

    # CBV 路由层
    url(r'^login/', views.MyCls.as_view()) # .的左边容器类型 # CBV 视图层
    from django.views import View
    from django.shortcuts import HttpResponse, render

    class MyCls(View): def get(self, request): return render(request, 'index.html') def post(self, request): return HttpResponse('post')

    2. JsonResponse对象

    是HttpRespon的子类,第一个参数是一个字典类型,

    返回json的字符串,

    json_dumps_params参数是一个字典,它将调用json.dumps()方法,'ensure_ascii'值为False时,传入的中文不会被编码为十六进制码

    from django.http import JsonResponse
    import json

    json.dumps(dict, ensure_ascii=False)
    def index9(request): dic = {'name': 'Tom的哥哥', 'age': 18} return JsonResponse(dic, json_dumps_params={'ensure_ascii': False}) 输出: {"name": "Tom的哥哥", "age": 18}


    3. 文件上传

    前端需注意:

    1. method 指定成 post(默认get)

    2. enctype 改为 formdata格式(默认urlencoded)

    后端注意点:

    1. 配置文件settings.py中,注释掉csrfmiddleware中间键

    2. 通过request.FILES 获取上传的post文件数据

    file_obj = request.FILES.get('my_file')
        with open(file_obj.name, 'wb') as f:
            for line in file_obj.chunks():
                f.write(line)

     

     

  • 相关阅读:
    在Mac电脑编译c51程序
    Unix程序员的Win10二三事
    macOS webview编程
    Day 6 文件属性与命令执行流程
    Day 5文件管理—三剑客的了解
    Day4 文件管理-常用命令
    Day3 目录结构及文件管理
    Day 2 Bash shell 认识
    Day 1 linux系统的发展史与虚拟机的安装过程
    【Offer】[66] 【构建乘积数组】
  • 原文地址:https://www.cnblogs.com/zhouyongv5/p/11000990.html
Copyright © 2011-2022 走看看