• 【Python百日进阶-WEB开发】Day166 - Django视图 View(一)


    一、视图介绍和项目准备

    在这里插入图片描述

    二、URLconf

    浏览者通过在浏览器的地址栏输入网址请求网站
    对于Django开发的网站,有哪一个视图进行处理请求,是由url匹配找到的,配置流程如下:

    2.1 settings.py中

    指定url配置:ROOT_URLCONF= ‘项目.urls’
    在这里插入图片描述

    2.2 项目urls.py

    匹配成功后,包含到应用的urls.py:path(‘’,include(‘应用.urls’))
    在这里插入图片描述

    2.3 应用 urls.py

    path(‘’,views.函数名)
    在这里插入图片描述

    2.4 提示

    • 如果使用正则匹配,推荐r’',不转义
    • 不能在开始加反斜杠(path(‘/path’)),推荐在结束加反斜杠(path(‘path/’))
    • 请求的url被看做是一个普通的python字符串,进行匹配时不包括域名、get和post参数,如请求地址:http://127.0.0.1:8000/18/?a=10,去掉域名和参数部分后,只剩下 18/ 进行正则匹配

    三、路由命名与reverse反解析

    3.1 路由命名

    在这里插入图片描述

    from django.urls import path
    from book.views import index
    
    urlpatterns = [
        # name就是url的名字,可以通过name找到这个路由
        path('index/', index, name='home'),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.2 reverse反解析,根据名字动态找路由

    在这里插入图片描述

    from django.http import HttpResponse
    from django.shortcuts import render, redirect, reverse
    from book.models import BookInfo, PeopleInfo
    # Create your views here.
    def index(request):
        """
        登录成功、注册成功等都需要跳转到首页
        1、不使用路由名字时的跳转页面
        return redirect('/index/')
        2、使用路由名字时的跳转页面,路由是动态获取
        path = reverse('index')
        return redirect(path)
        """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.3 namespace 应用命名空间

    3.3.1 项目urls中定义namespace

    在这里插入图片描述

    from django.contrib import admin
    from django.urls import path, include
    from book.views import index
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        # 在include中添加第二参数 namespace,这样原来路由的name就变成了 namespace:name, 如 book:home
        # namespace习惯上使用子应用的名字,容易识别还不会重名
        path('', include('book.urls', namespace='book')),
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.3.2 book应用urls中定义app_name

    在这里插入图片描述

    from django.urls import path
    from book.views import index
    
    app_name = 'book'
    
    urlpatterns = [
        # name就是url的名字,可以通过name找到这个路由
        path('index/', index, name='home'),
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.3.3 应用Views中使用namespace:name反解析

    在这里插入图片描述

    from django.shortcuts import render, redirect, reverse
    from book.models import BookInfo, PeopleInfo
    # Create your views here.
    def index(request):
        """
        登录成功、注册成功等都需要跳转到首页
        1、不使用路由名字时的跳转页面
            return redirect('/index/')
        2、使用路由名字时的跳转页面,路由是动态获取
            path = reverse('home')
            return redirect(path)
        3、如果设置了namespace就需要通过namespace:name来获取路由
            path = reverse('book:home')
            return redirect(path)
        """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    四、使用PostMan对请求进行测试

    PostMan是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件,可以直接去对我们写出来的路由和视图函数进行调试,是后端程序员必须会用的一个工具。

    4.1 安装方式

    4.1.1 Chrome商店直接搜索PostMan扩展程序进行安装

    4.1.2 官网下载桌面版https://www.postman.com/downloads/

    在这里插入图片描述
    安装
    在这里插入图片描述
    注册免费账号,
    在这里插入图片描述
    在这里插入图片描述
    保存账号密码,省得每次都得输入
    在这里插入图片描述

    4.1.3 将已下载好的PostMan插件文件夹拖入Chrome浏览器

    4.2 使用方法

    在这里插入图片描述

    在这里插入图片描述

    五、HttpRequest对象

    利用HTTP协议向服务器传参有四种途径:

    • 提取URL的特定部分如/weather/beijing/2018,可以在服务器端的路由中用正则表达式截取;
    • 查询字符串( query string),形如key1=alue&key=value2;
    • 请求体(body)中发送的数据,比如表单数据、json、xml等
    • 在http报文的头(header)中

    5.1 URL路径参数

    • 如果想从URL中获取值,需要在正则表达式中使用分组
    • 获取值分为两种方式
      – 位置参数:参数的位置不能错
      –关键字参数:参数的位置可以变,跟关键字保持一致即可
    • 注意:两种参数的方式不要混合使用,在一个正则表达式中只能使用一种参数方式
    • 分别使用以上两种获取URL值的方式提取出18 188

    5.1.1 位置参数

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

    在这里插入图片描述
    在这里插入图片描述
    正则分组匹配所有整数数字 (\d+)
    在这里插入图片描述

    from django.urls import path
    from book.views import index, detail
    from django.conf.urls import url
    
    app_name = 'book'
    
    urlpatterns = [
        # name就是url的名字,可以通过name找到这个路由
        path('index/', index, name='home'),
        # http://127.0.0.1:8000/category_id/book_id
        # 根据位置来获取url中传递的参数
        url(r'^(\d+)/(\d+)/$', detail),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5.1.2 关键字参数

    利用正则别名(?P\d+)传递关键字,推荐使用,不用考虑位置问题,只要关键字对应就行。
    在这里插入图片描述
    在这里插入图片描述
    实际项目路由都是关键字参数
    在这里插入图片描述
    在这里插入图片描述

    from django.urls import path
    from book.views import index, detail1, detail2
    from django.conf.urls import url
    
    app_name = 'book'
    
    urlpatterns = [
        # name就是url的名字,可以通过name找到这个路由
        path('index/', index, name='home'),
        # http://127.0.0.1:8000/category_id/book_id
        # 根据位置来获取url中传递的参数
        url(r'^(\d+)/(\d+)/$', detail1),
        # 关键字传递参数,推荐使用
        url(r'^(?P\d+)/(?P\d+)/$', detail2),
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    # 关键字传递参数,函数接收关键字
    def detail2(request, categeory_id, book_id):
        print(categeory_id, book_id)
        return HttpResponse('detail')
    
    • 1
    • 2
    • 3
    • 4

    5.2 查询字符串

    获取请求路径中的查询字符串参数(形如?1=v1&k2=v2),可以通过 requestget属性获取,返回QueryDict对象。
    注意:查询字符串不区分请求方式,即假使客户端进行POST方式的请求,依然可以通过 request GET获取请求中的查询字符串数据。
    PostMan模拟 在这里插入图片描述

    5.2.1查询关键字通过 request.GET 参数接收

    在这里插入图片描述

    5.2.2Django中的QueryDict对象与普通python字典的区别

    HttpRequest对象的属性GET、POST都是QueryDict类型的对象
    与python字典不同, QueryDict类型的对象用来处理同一个键带有多个值的情况

    • 方法get:根据键获取值,get(‘key’, 默认值)
      如果一个键同时拥有多个值将获取最后一个值
      如果键不存在则返回None值,可以设置默认值进行后续处理
    • 方法 getlist():根据键获取值,值以列表返回可以获取指定键的所有值,getlist(键,默认值)
      如果键不存在则返回空列表,可以设置默认值进行后续处理

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

    # 查询字符串
    def detail3(request, categeory_id, book_id):
        """
        查询字符串,以百度查询python为例
        https://www.baidu.com/s?wd=python&rsv_spt=1&rsv_iqid=0x8662fdc7003bb4a1&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=49055317_10_hao_pg&rsv_enter=1&rsv_dl=ib&rsv_sug3=17&rsv_sug1=16&rsv_sug7=100
        上面的url以问号作为分隔,前面是路由,https://www.baidu.com/s
        问号后面是get传递的参数,称之为查询字符串,它的形式是,?key=value&key=value&key=value...
        成熟系统中,用户在登录输入用户名和密码的时候,理论上,用户名和密码都应该以POST方式进行传递
        现在,为了便于学习,采用get方式传递用户名和密码
        get传递的用户名和密码在 request.GET 中
        """
        # 前端:http://127.0.0.1:8000/2/200?user_name=zhangsan&password=123
        # query_params = request.GET
        # print(query_params)             # 
        # print(type(query_params))       # 
        # # 后台获取用户名密码
        # user_name = query_params['user_name']
        # print(user_name)                  # zhangsan
        # password = query_params.get('password')
        # print(password)                   # 123
        """
        QueryDict 与普通python字典的区别
            1、QueryDict可以获取url中的一键多值,以 key:[value1, ..., value2] 的形式存储
            2、QueryDict获取的一键多值,以普通字典key的方式提取,只能提取到最后的一个值(value2),不能提取到值列表[value1, ..., value2]
            3、想获取QueryDict的一键多值,需要用QueryDict的getlist方法,形如:QueryDict.getlist('user_name')
        """
        # 前端:http://127.0.0.1:8000/2/200?user_name=zhangsan&password=123&user_name=lisi
        query_params = request.GET
        print(query_params)             # 
        print(type(query_params))       # 
        # 后台获取用户名密码
        user_name = query_params['user_name']       # 字典key方法,只能获取一键多值的最后一个
        print(user_name)                # lisi
        users = query_params.getlist('user_name')   # QueryDict.getlist方法,可以获取一键多值的值列表
        print(users)                    # ['zhangsan', 'lisi']
        password = query_params.get('password')     # QueryDict.get方法,同字典key方法
        print(password)                 # 123
    
        return HttpResponse('detail-3')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    5.3 请求体

    请求体数据格式不固定,可以是表单类型字符串,可以是JSON字符串,可以是ML字符串应区别对待,
    可以发送请求体数据的请求方式有 POST、PUT、PATCH、DELETE。
    Django默认开后了CSRF防护,会对上述请求方式进行CSRF防护验证,在测试时可以关闭CSRF防护机制,方法为在 settings py文件中注释掉CSRF中间件。
    注意:①网址url以斜线结束。②注释掉settings中的CRSF安全设置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    5.3.1 POST表单数据

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

    # POST表单数据,
    def detail4(request, categeory_id, book_id):
        print(categeory_id, book_id)
        """
        1、使用request.POST方法获取前端传输的数据
        2、request.POST方法获取的结果为QueryDict,与request.GET获取的结果是样的
        3、一键一值和一键多值的数据处理方式与GET方法完全相同
        """
        data = request.POST
        print(data)                         # 
        user_name = data['user_name']
        print(user_name)                    # lisi
        user_name = data.get('user_name')
        print(user_name)                    # lisi
        users = data.getlist('user_name')
        print(users)                        # ['zhangsan', 'lisi']
        password = data.get('password')
        print(password)                     # 123
        return HttpResponse('detail-4')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    5.3.2 POST json 数据

    非表单类型的请求体数据, Django无法自动解析,可以通过 request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON/XML等)进行解析 request.body返 bytes回类型,然后通过decode()解码为JSON形式的字符串数据,再通过json.loads()转换为字典数据,就可使用了。
    在这里插入图片描述
    在这里插入图片描述

    # POST  JSON数据,
    def detail5(request, categeory_id, book_id):
        import json
        print(categeory_id, book_id)
        """
        1、json数据的样式,注意:①只能用双引号,不能用单引号。②最好一行数据后面不能加逗号
            {
                "user_name": "zhangsan",
                "password": "123"
            }
        2、通过Ajax发送的JSON数据并没有记录在 request.POST 中,而是记录在 request.body 中
        3、request.body获取到的是bytes类型数据,可以通过decode()转换为JSON形式的str类型,再通过json.loads转换为字典
        4、json模块:
            json.dumps,将字典转换为JSON形式的字符串
            json.loads,将JSON形式的字符串转换为字典
        """
        data = request.POST
        print(data)                         # 
        body = request.body
        print(body)                         # b'{\r\n    "user_name":"zhangsan",\r\n    "password":"123"\r\n}'
        print(type(body))                   # 
        body_str = body.decode()            # 对bytes数据解码,结果为str
        print(body_str)                     # {
                                            #     "user_name": "zhangsan",
                                            #     "password": "123"
                                            # }
        print(type(body_str))               # 
        body_dict = json.loads(body_str)    # 将JSON形式的字符串转换为字典
        print(body_dict)                    # {'user_name': 'zhangsan', 'password': '123'}
        print(type(body_dict))              # 
        return HttpResponse('detail-5')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    5.4 http报文头(header) request.META

    可以通过 request.META属性获取请求头headers中的数据,request.META为字典类型。
    常见的请求头如:

    • CONTENT_LENGTH-The length of the request body (as a string).
    • CONTENT_TYPE-The MIME type of the request body.
    • HTTP ACCEPT-Acceptable content types for the response.
    • HTTP_ACCEPT_ENCODING-Acceptable encodings for the response.
    • HTTP_ACCEPT_LANGUAGE-Acceptable languages for the response.
    • HTTP host-the http host header sent by the client
    • HTTP_REFERER-The referring page, if any
    • HTTP_USER_AGENT-The client’s user-agent string.
    • QUERY_STRING-The query string, as a single (unparsed)string.
    • REMOTE ADDR-The iP address of the client
    • REMOTE HOST The hostname of the client
    • REMOTE_USER-The user authenticated by the Web server, if any.
    • REQUEST METHOD-A string such as "GET"or “POST”
    • SERVER NAME- The hostname of the server.
    • SERVER_PORT-The port of the server (as a string)
      在这里插入图片描述
      在这里插入图片描述
    # http报文头(header) request.META
    def detail6(request, categeory_id, book_id):
        # print(request.META)
        content_type = request.META['CONTENT_TYPE']
        print(content_type)                 # text/plain
        name = request.META['HTTP_NAME']
        print(name)                         # ruhua
    
        return HttpResponse('detail-6')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5.5 其他常见HttpRequest对象属性

    • method :一个字符串,表示请求使用的HTP方法,常用值包括:get’pos
    • user:请求的用户对象
    • path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分
    • encoding:一个字符串,表示提交的数据的编码方式
      - 如果为None则表示使用浏览器的默认设置,一般为utf-8
      - 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的 encoding值。
    • FILES:一个类似于字典的对象,包含所有的上传文件
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    # 其他常见HttpRequest对象属性
    def detail7(request, categeory_id, book_id):
        print(request.method)
        return HttpResponse('detail-7')
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    HttpUtil
    蓄电池智能监控系统,蓄电池智能监控系统的作用
    C#实现QQ窗体的步骤和总结
    使用Linux JumpServer 堡垒机进行远程访问
    Java零基础-进制转换
    关键词搜索排行榜-精准找到行业流量关键词
    什么是网络端口
    (01)ORB-SLAM2源码无死角解析-(53) 闭环检测→了解闭环检测、
    公网使用PLSQL远程连接Oracle数据库【内网穿透】
    Hadoop-HA节点介绍
  • 原文地址:https://blog.csdn.net/yuetaope/article/details/123000166