一、认识http请求
django视图中的request(包含了请求信息的请求对象)
(一)请求的方式
-
get
- 默认的页面请求方式,是get请求,是在web中使用最频繁的请求方式
- 请求服务器资源,可以携带参数,参数在url中,不安全,反爬能力弱
- https://www.baidu.com/s?wd=world&rsv_spt=1
- 参数以?开始,多个参数由&连接
- 参数格式:key=value
-
post
- 向服务器提供资源,数据包含在请求体当中,隐藏传递,安全性比get请求高,传输数据的量比get请求大
-
delete
-
options
-
put
-
patch
-
head
(二)响应码
相当于给常见错误定了一个唯一标识。
- 100 服务器收到请求,需要用户继续操作,例如:发出请求,但是需要用户继续输入密码
- 101 根据客户端需求转换协议
- 200 请求成功,服务器成功处理了请求
- 202 请求已经被接受,但是还没有处理完
- 300 请求重定向
- 303 对应当前的需求,需要在另一个URL地址中才能找到,客户端通过get请求方式去访问那个地址
- 400 客服端错误
- 403 CSRF,服务器理解了请求,但是拒绝了
- 404 页面找不到,路径问题
- 500 服务端错误
- 502 bad gateway,服务器错误,代理问题
(三)请求对象的属性
request.COOKIES | 用户身份 |
---|---|
request.FILES | 请求携带的的文件,比如图片 |
request.GET | get请求携带的参数 |
request.POST | post请求携带的参数 |
request.scheme | 请求协议,https还是http |
request.method | 请求的方式 |
request.path | 请求的路径 |
request.body | 请求的主体,返回的是一个字符串 |
print(request) # <WSGIRequest: GET '/reqtest/'>
print(request.COOKIES)
print(request.FILES)
print(request.GET)
print(request.POST)
print(request.scheme)
print(request.method)
print(request.path)
print(request.body)
'''
{'csrftoken': 'ooZW5tFBeWxSLCSWnoF6s4i5v70Gand4rG6vWyCe0xlDYpALBIZ8JsjOLVYOVpxX', 'sessionid': 'rivuz36fiw91hzjsjbo7lhjeo1dvs1wu'}
<MultiValueDict: {}>
<QueryDict: {}>
<QueryDict: {}>
http
GET
/reqtest/
b''
'''
request.META | 包含了具体的请求数据,包含了所有http请求的信息,是一个字典 |
---|---|
request.META[‘OS’] | 请求的系统 |
request.META[‘HTTP_USER_AGENT’] | 发出请求的浏览器版本 |
request.META[‘HTTP_HOST’] | 请求的主机 |
request.META[‘HTTP_REFERER’] | 请求的来源 |
print(request.META['OS'])
print(request.META['HTTP_USER_AGENT'])
print(request.META['HTTP_HOST'])
print(request.META.get('HTTP_REFERER'))
'''
Windows_NT
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
127.0.0.1:8000
None
'''
(四)获取请求传递的参数
get
post
发送post请求的时候,会报403(csrf 跨站请求伪造),因为Django自动开启了csrf验证
解决:
将settings.py中的中间件中的csrf验证注释掉(MIDDLEWARE中的’django.middleware.csrf.CsrfViewMiddleware’)
二、Django的form表单类
(一)form表单
form 创建一个表单域
action 提交的地址
method 提交的方式 get/post
input
select
submit
button
(二)form表单get请求
-
templates中创建formtest.html放入form表单
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表单</title> </head> <body> <form action=""> <input type="text" name="search"> <input type="submit" value="提交"> </form> </body> </html>
-
视图
1.get demo:进一步利用获取的数据–实现文章标题的模糊查询
(三)form表单post请求
1.CSRF
跨站请求伪造攻击,使用当前浏览器还在生效的cookie对指定网站进行操作,最初针对的是银行系统。
2.POST请求
django本身提供对csrf的校验功能,在django1.4版本之前,是需要手动开启的。
在django的所有的post请求,都会在请求之初,给用户下发一个串用来校验身份的编码,并且每次请求下发的串都不一样。django的csrf只针对post请求。
django中使用csrf的步骤:
结果:
3.post demo:获取用户名、密码,保存到数据库完成注册
-
模板register.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册</title> </head> <body> <form action="" method="post"> {% csrf_token %} 用户名:<input type="text" name="username"><br> 密 码:<input type="password" name="password"><br> 确认密码:<input type="password" name="password2"><br> <input type="submit" value="注册"> <p style="color:red;font-size: 20px">{{ result }}</p> </form> </body> </html>
-
视图
def register(request): if request.method == 'POST': # 获取数据 username = request.POST.get('username') password = request.POST.get('password') password2 = request.POST.get('password2') # 判断数据是否完整 if username and password and password2: if password2 != password: result='两次密码不一致' else: user = User() user.name=username user.password=password user.save() result = '注册成功' else: result='请完成输入' return render(request,'register.html',locals())
使用md5实现密码加密
加密:md5,不可逆的加密,string->密文 password->密文
加密函数:
import hashlib
def setPassword(password):
# 实现密码加密
md5 = hashlib.md5() # 创建一个md5的实例对象
md5.update(password.encode()) # 进行加密
result = md5.hexdigest()
return result
修改视图:
结果:
登录
新建模板login.html
视图
def login(request):
if request.method == 'POST':
data = User.objects.filter(name=request.POST.get('username')).first()
if data:
if setPassword(request.POST.get('password'))==data.password:
result = '登录成功'
else:
result = '密码错误'
else:
result = '不存在此用户'
return render(request,'login.html',locals())
路由
(四)django form表单类
表单功能在实际开发中,完成对数据的校验和获取数据的任务。所谓数据校验:包括对数据长度、数据类型、是否为空、是否符合格式的校验。
例如,用户名:长度限制,特殊字符,用户名是否存在
- 前端校验
- 通过js或者jq脚本对form表单提交的数据进行校验
- 优点:形象,直观,减少服务器压力,有利于对用户提醒,用户体验较好
- 后端校验
- 在视图中,对要存储的数据进行校验,需要后端编写
- 优点:安全性高
- 缺点:服务器压力大,比较复杂
django前端校验可以通过校验框架进行校验,django推出form表单类来进行校验
1.表单类的使用
1.新建forms.py文件,定义form表单类
2.使用form表单类
form表单类是django定义的,可以自动生成前端form表单代码的一个表单类,已完成大部分的校验功能。
2.常见的样式
table样式:as_table被闲置,样式跟普通样式无区别。因为以前的布局使用的是table布局,现在用的是div布局,没有任何样式。
修改table样式
django提供的form表单类中只提供了样式,没有form表单域,也没有提交按钮。
优点:方便开发人员修改样式
如果需要提交,需要在外面包围一个form标签。
3.使用form表单类实现注册功能
模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<table>
{% for one in register_form %}
<tr>
<th>
{{ one.label }}
</th>
<td>
{{ one }}
</td>
</tr>
{% endfor %}
<tr>
<th>
<input type="submit" value="提交">
</th>
</tr>
</table>
</form>
</body>
</html>
视图:
from Article.forms import Register
def register(request):
register_form = Register()
if request.method == 'POST':
# 获取数据
# username = request.POST.get('username')
username = request.POST.get('name')
password = request.POST.get('password')
# 判断数据是否完整
if username and password:
user = User()
user.name=username
user.password=setPassword(password)
user.save()
result = '注册成功'
else:
result='请完成输入'
return render(request,'register.html',locals())
还可以使用form表单类,通过字段属性进行数据的校验。
max_length 最大长度
min_length 最小长度
required=True 是否允许为空,默认为True,不可为空
label form表单类的标签内容
help_text 帮助文档,有的浏览器显示不出来
4.使用form表单类进行后端验证
模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
{% for one in register_form %}
<p>
{{ one.label }}
{{ one }}
</p>
{% endfor %}
<p>
<input type="submit" value="提交">
</p>
</form>
{{ result }}
</body>
</html>
表单类
from django import forms
class Register(forms.Form):
name = forms.CharField(required=True,label='姓名')
password = forms.CharField(max_length=8,min_length=6,label='密码')
# 固定写法
def clean_name(self):
'''
自定义验证
用户名不允许是admin
'''
name=self.cleaned_data.get('name')
if name == 'admin':
self.add_error('name','用户名不可以是admin')
else:
return name
视图
from Article.forms import Register
# 使用form表单进行后端验证
def register(request):
register_form = Register()
if request.method == 'POST':
# 获取数据
data = Register(request.POST)
# 校验是否通过 通过True,否则False
if data.is_valid():
# 返回一个字典类型,通过校验的数据
clean_data=data.cleaned_data
# 获取到数据,写库
username=clean_data.get('name')
password=clean_data.get('password')
user = User()
user.name=username
user.password=setPassword(password)
user.save()
result = '注册成功'
else:
result=data.errors
print(result)
return render(request,'register.html',locals())