Django表单

Posted 礁之

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django表单相关的知识,希望对你有一定的参考价值。

文章目录


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

Django版本:

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

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)
  • 在模板目录中添加search_from.html,路径为/HelloWorld/templates/search_from.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GET_test</title>
</head>
<body>
    <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="搜索">
    </form>
</body>
</html>
  • 修改/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),
]
  • 访问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_TEST</title>
</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>

模板末尾的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)
  • 修改文件/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),
]
  • 访问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!!!")
  • 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都是<input type="file" name=""/>标签中name属性的值,FILES中的每个value同时也是一个标准的Python字典对象,包含下面三个Keys:
(1)filename:上传文件名,使用Python字符串表示
(2)content-type:上传文件的Content type
(3)content:上传文件的原始内容
注意:只有再请求方式是POST、并且请求页面中的<from>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”

以上是关于Django表单的主要内容,如果未能解决你的问题,请参考以下文章

Django基础学习笔记

使用 django 频道的 heroku 的正确 procfile / 要求是啥?

写一个简单的 django_post demo

我正在使用 angularjs 和 django-cors-headers 然后给出“这对于需要预检的跨域请求是不允许的。”

我的请求是跨源请求吗?(heroku 上的 Django rest api,CORS 没有阻止我的请求)

如何摆脱在子表单末尾添加新记录?