Django表单
Posted 礁之
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django表单相关的知识,希望对你有一定的参考价值。
文章目录
此文章参考菜鸟教程:Django 表单 | 菜鸟教程 (runoob.com)
Django版本:
>>> django.VERSION
(4, 1, 0, 'final', 0)
PS:基于前几章的进度进行修改
一、概述
- 表单在网页中主要负责数据采集功能。一个表单有三个基本组成部分:
- 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法。
- 表单域:包含了文本框、密码框、隐藏域、多行文本框、复选框、单选框、下拉选择框和文件上传框等。
- 表单按钮:包括提交按钮、复位按钮和一般按钮;用于将数据传送到服务器上的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 频道的 heroku 的正确 procfile / 要求是啥?
我正在使用 angularjs 和 django-cors-headers 然后给出“这对于需要预检的跨域请求是不允许的。”