• Django(4)表单



    此文章参考菜鸟教程:Django 表单 | 菜鸟教程 (runoob.com)

    Django版本:

    >>> django.VERSION  
    (4, 1, 0, 'final', 0)
    
    • 1
    • 2

    PS:基于前几章的进度进行修改

    一、概述

    • 表单在网页中主要负责数据采集功能。一个表单有三个基本组成部分:
    1. 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法。
    2. 表单域:包含了文本框、密码框、隐藏域、多行文本框、复选框、单选框、下拉选择框和文件上传框等。
    3. 表单按钮:包括提交按钮、复位按钮和一般按钮;用于将数据传送到服务器上的CGI脚本或者取消输入,还可以用表单按钮来控制其他定义了处理脚本的处理工作。

    注释:CGI为通用网关接口

    • HTML表单是网站交互性的经典方式
    • HTTP协议以请求——回复的方式工作,当客户发送请求时,可以在请求中附加数据,服务器通过解析请求,从而获得客户传输的数据,并根据URL来提供特定的服务

    二、GET方法

    • 继续之前的项目,创建/HelloWorld/HelloWorld/search.py文件,用于接收用户的请求:
    # -*- coding: utf-8 -*-
    from django.http import HttpResponse
    from django.shortcuts import render
    
    def search_from(request):  
        return render(request,'search_from.html')   #指定表单
    
    def search(request):  #接收请求数据
        request.encoding = 'utf-8'
        if 'q' in request.GET and request.GET['q']:   #对接收数据进行判断
            message = '你搜索的内容为:' + request.GET['q']
        else:
            message = '你提交了空表单'
        return HttpResponse(message)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 在模板目录中添加search_from.html,路径为/HelloWorld/templates/search_from.html
    DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>GET_testtitle>
    head>
    <body>
        <form action="/search/" method="get">
            <input type="text" name="q">
            <input type="submit" value="搜索">
        form>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 修改/HelloWorld/HelloWorld/urls.py
    #-*- coding: utf-8 -*-
    from django.urls import path
    
    from . import index_test,testdb,search   #导入search.py
    
    urlpatterns = [
        path('hello/',index_test.Hello),
        path('testdb/',testdb.testdb),
        path('search-from/',search.search_from),  #增加两个path,指定search.py的两个方法
        path('search/',search.search),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 访问IP:8000/search-from

    访问search-from资源时会调用search_from方法,此方法会提交search_from.html表单,表单使用GET方式去访问search资源,然后开始执行search方法,最终输出你搜索的内容为:Test
    在这里插入图片描述
    在这里插入图片描述

    • 访问IP:8000/search

    因为没有经过上面提交表单的操作,所以在执行search方法时,是没有q参数的,所以判定false,输出你提交了空表单

    在这里插入图片描述

    三、POST方法

    • 上面使用了GET方法,视图显示和请求处理分成了两个函数处理
    • 下面来看POST方法,下面方法使用一个URL和一个处理函数,同时显示视图和处理请求,下面创建文件/HelloWorld/templates/post.html
    DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>POST_TESTtitle>
    head>
    <body>
        <form action="/search-post/" method="post">
            {% csrf_token %}
            <input type="text" name="q">
            <input type="submit" value="搜索">
        form>
     
        <p>{{ rlt }}p>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    模板末尾的rlt记号,用于为表格处理结果预留位置,表格后面还有一个{% csrf_token %}标签

    注意:csrf全称 Cross Site Request Forgery ,这是 Django 提供的防止伪装提交请求的功能。POST 方法提交的表格,必须有此标签

    • 新建文件/HelloWorld/HelloWorld/search2.py
    # -*- coding: utf-8 -*-
     
    from django.shortcuts import render
    from django.views.decorators import csrf
     
    
    def search_post(request):  # 接收POST请求数据
        ctx ={}
        if request.POST:
            ctx['rlt'] = request.POST['q']
        return render(request, "post.html", ctx)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 修改文件/HelloWorld/HelloWorld/urls.py
    #-*- coding: utf-8 -*-
    from django.urls import path
    
    from . import index_test,testdb,search,search2
    
    urlpatterns = [
        path('hello/',index_test.Hello),
        path('testdb/',testdb.testdb),
        path('search-from',search.search_from),
        path('search/',search.search),
        path('search-post',search2.search_post),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 访问IP:8000/search-post

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

    访问search-post资源时会调用search_post方法,然后提交post.html表单,表单调用/search-post/并且把输入的文本定义到ctx字典中,并定义键值,最终表单末尾进行调用{{ rlt }},这样的效果就是输入任何文本,会输出任何文本

    • 下面是现在的目录结构

    在这里插入图片描述

    四、Request对象

    • 每个视图函数的第一个参数是HttpRequest对象,例如:
    from django.http import HttpResponse
    
    def test(request):
        return HttpResponse("Hello World!!!")
    
    • 1
    • 2
    • 3
    • 4
    • HttpRequest对象包含当前请求URL的一些信息:
    属性描述
    path请求页面的全路径,不包括域名,也就是访问资源,例如:“/hello/”
    method请求中使用的HTTP方法的字符串表示,全大写表示,例如:
    if request.method == ‘GET’:
    do_something()
    elif request.method == ‘POST’:
    do_something_else()
    GET包含所有HTTP GET参数的类字典对象
    POST包含所有HTTP POST参数的类字典对象
    注意:服务器是有可能收到空POST请求的,也就是说,表单from通过POST方式提交时,是可以没有数据的,因此如果要判断是否使用POST方法,应该使用if request.method == "POST"而不是if request.POST
    REQUEST该属性是POST和GET属性的集合体,但是有特殊性,先查找POST属性,然后再找GET属性,例如:
    如果GET = {"name":"zhangsan"}POST = {"age":"22"},那么REQUEST["name"] = "zhangsan",REQUEST["age"] = "22"
    COOKIES包含所有cookies的标准Python字典对象,Keys和values都是字符串
    FILES包含所有上传文件的类字典对象,FILES中的每个Key都是标签中name属性的值,FILES中的每个value同时也是一个标准的Python字典对象,包含下面三个Keys:
    (1)filename:上传文件名,使用Python字符串表示
    (2)content-type:上传文件的Content type
    (3)content:上传文件的原始内容
    注意:只有再请求方式是POST、并且请求页面中的enctype="multipart/form-data"属性时,FILES才拥有数据,否则FILES就是一个空字典
    META包含所有可用的HTTPS头部信息的字典,例如:
    (1)CONTENT_LENGTH
    (2)CONTENT_TYPE
    (3)QUERY_STRING:未解析的原始查询字符串
    (4)REMOTE_ADDR:客户端IP地址
    (5)REMOTE_HOST:客户端主机名
    (6)SERVER_NAME: 服务器主机名
    (7)SERVER_PORT:服务器端口
    META 中这些头加上前缀HTTP_为 Key, 冒号(:)后面的为 Value, 例如:
    user这是一个django.contrib.auth.models.User对象,代表当前登录的用户,如果访问用户当前没有登录,user将被初始化为django.contrib.auth.models.AnonymousUser的实例,可以通过user的is_authenticated()方法来辨识用户是否登录
    if request.user.is_authenticated():
    # Do something for logged-in users.
    else:
    # Do something for anonymous users.
    只有激活Django中的AuthenticationMiddleware时,该属性才可用
    session唯一可读写的属性,代表当前会话的字典对象,只有激活Django中的sesion支持时该属性才可用
    raw_post_data原始HTTP POST数据,未解析过,高级处理时有用
    • Request对象也有一些有用的方法
    方法描述
    __getitem__(key)返回GET/POST的键值,先取POST,后取GET,如果键不存在则输出KeyError,可用使用字典语法访问HttpRequest对象,例如:
    request["foo"]等同于先request.POST["foo"] 然后再request.GET["foo"]的操作。
    has_key()检查request.GET or request.POST中是否包含参数指定的Key
    get_full_path()返回包含查询字符串的请求路径,例如:
    "/music/bands/the_beatles/?print=true"
    is_secure()如果请求是安全的,返回True,也就说明发出的请求是HTTPS的

    五、QueryDict对象

    • 在HttpRequest对象中,GET和POST属性是django.http.QueryDict类的实例

    • QueryDict类似字典的自定义类,用来处理单键对应多值的情况

    • QueryDict实现所有标准的词典方法,还有一些特有的方法,例如:

    方法描述
    __getitem__和标准字典的处理不同的是,如果Key对应多个Value,那么__getitem__()将会返回最后一个value
    __setitem__设置参数指定Key的Value列表(一个Python列表)
    注意:它只能在一个mutable QueryDict对象上被调用,此对象是通过copy()产生的一个QueryDict对象的拷贝
    get()如果Key对应多个Value,那么get()会返回最后一个Value
    update()参数可以是QueryDict,也可以是标准字典,但是和标准字典的update()方法不同的是,该方法添加字典items,而不是替换
    items()和标准字典的items()方法有一点不同,该方法使用单值逻辑的__getitem__()
    values()和标准字典的values()方法有一点不同,该方法使用单值逻辑的__getitem__()
    • 除此之外,QueryDict也有一些方法:
    copy()返回对象的拷贝,内部实现是用Python标准库的copy.deepcopy()。该拷贝是mutable(可更改的) 也就是说,可以更改该拷贝的值
    getlist(key)返回和参数Key对应的所有值,作为一个Python 列表返回。如果Key不存在,则返回空列表
    setlist(key,list_)设置Key的值为list_ (unlike __setitem__())
    appendlist(key,item)添加item到和Key关联的内部list.
    setlistdefault(key,list)setdefault有一点不同,它接受列表而不是单个Value作为参数
    lists()和items()有一点不同, 它会返回key的所有值,作为一个列表
    urlencode()返回一个以查询字符串格式进行格式化后的字符串,例如:“a=2&b=3&b=5”
  • 相关阅读:
    从中序遍历和后序遍历构建二叉树
    WebRTC Simulcast测试--用Janus
    asp.net core mvc 路由
    微机原理——汇编指令(上部)
    ChatGPT AIGC 快速合并Excel工作薄 Vlookup+INDIRECT
    Java面向对象之——继承
    设计模式学习笔记(二十)状态模式及其实现
    C#使用 AutoUpdater.NET 实现程序自动更新
    详细讲解什么是工厂模式
    [附源码]计算机毕业设计springboot茶叶销售微信小程序
  • 原文地址:https://blog.csdn.net/rzy1248873545/article/details/126664666