文章目录
一、Django 请求
from表单 是前端的知识点,和后端没有很大的关系,无论哪门语言作为后端,前端是一致的:
action 表单数据提交到的路径
method 提交的方式
enctype 提交数据的类型,针对文件(图片)
name 所有表单元素的单词。
(一)常见的请求方式
默认页面请求都是GET请求。
视图函数中request是传递到视图的请求,里面包含请求的各种参数。
常用的请求方式get和post:
- get:默认是get请求,请求数据以明文形式放在路由上,get的格式是以?开头,键值对形式,以&分割键值对,通常用于向服务器获取资源。
- post:请求数据隐藏发送,安全系数更高。通常用于向服务器提交资源。
其他请求还有:PUT、DELETE、OPTION
(二)请求状态码
200:(成功) 服务器已成功处理了请求。
300:(重定向) 表示要完成请求,需要进一步操作。
400:(请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
500:(服务器错误)表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
上述知识点属于前端和HTTP协议,是所有web开发共性知识。部分需要特殊掌握。
(三)Django请求对象
Django通过视图函数定义的第一个参数来接收请求,接收到是WSGIRequest对象,里面包含了整个请求所有的参数,常用的:
参数 | 描述 |
---|---|
request.GET | 接收get请求的参数 |
request.POST | 接收post请求的参数 |
request.FILES | 接收文件数据 |
request.method | 请求方式 |
request.META | 请求的细节参数 |
request.META.OS | 请求的系统类型 |
request.META.HTTP_USER_AGENT | 请求的浏览器版本 |
request.META.HTTP_HOST | 主机地址 |
request.META.HTTP_REFERER | 请求的来源 |
二、Django表单
表单提交案例:、
1、定义数据库模型
class Store(models.Model):
s_name = models.CharField(max_length = 32) #名称
s_address = models.TextField() #地址
s_description = models.TextField() # 描述
s_picture = models.ImageField(upload_to = "img") # 地址
imagefield需要配置upload_to来声明地址,这个地址需要和settings当中的MEDIA_ROOT结合
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR,"static")
MEDIA_ROOT+upload_to的地址 = 文件保存的目录
2、前端构建表单
<form method="post" enctype="multipart/form-data">
<table class="table store_table">
<tr>
<td rowspan="4">
<a href="#" class="thumbnail">
<img src="/static/img/by.jpg">
</a>
</td>
<th class="t_label">店铺名称</th>
<td class="t_input"><input name="s_name" class="form-control" type="text" placeholder="店铺名称"></td>
<td class="t_message",style="">店铺名称每月至多修改一次</td>
</tr>
<tr>
<th class="t_label">店铺地址</th>
<td class="t_input" colspan="2">
<input class="form-control" name="s_address" type="text" placeholder="店铺地址">
</td>
</tr>
<tr>
<th colspan="3">店铺描述</th>
</tr>
<tr>
<td colspan="3">
<textarea class="form-control" name="s_description"></textarea>
</td>
</tr>
<tr>
<td>
<input class="btn btn-primary" type="file" name="s_picture" value="图片上传">
</td>
<td colspan="3">
<input class="btn btn-primary" type="submit" value="发起修改">
</td>
</tr>
</table>
</form>
3、后端接收保存数据
注释掉 csrf 中间件:
默认django开启了csrf保护,可以通过注释settings配置来控制csrf的开关
from Goods.models import *
def store(request):
"""天天生鲜-店铺管理"""
if request.method == "POST": #判断请求的类型
#使用 request.POST接收数据
s_name = request.POST.get("s_name")
s_address = request.POST.get("s_address")
s_description = request.POST.get("s_description")
s_picture = request.FILES.get("s_picture")
#保存数据
s = Store()
s.s_name = s_name
s.s_address = s_address
s.s_description = s_description
s.s_picture = s_picture #图片可以直接保存
s.save()
return render_to_response("store.html")
三、Django CSRF
django csrf保护是通过中间件来实现的,在1.1之前django默认关闭csrf,后来默认开启
MIDDLEWARE = [
...
'django.middleware.csrf.CsrfViewMiddleware',
...
]
在表单当中添加csrf的方法:
1、在HTML当中添加CSRF标签
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<table class="table store_table">
<tr>
<td rowspan="4">
2、视图需要切换render方法进行返回,render和render_to_response的区别在于render方法传递request请求到前端,这样才可以调用到csrf
def store(request):
"""天天生鲜-店铺管理"""
if request.method == "POST": #判断请求的类型
....
return render(request,"store.html")
3、在实际工作当中,有的视图需要单独取消csrf保护
from Goods.models import *
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def store(request):
"""天天生鲜-店铺管理"""
.....
四、Django后端表单校验
(一)表单类
在app当中可以定义表单类,用来渲染和进行后端数据校验
定义好的form类可以通过前端渲染成表格格式,渲染提供了三个便利的方法
方法 | 描述 |
---|---|
as_p | 使用p标签包含单个表单项 |
as_ul | 使用li标签包含单个表单项 |
as_table | 使用tr标签包含单个表单项,但是在1.8版本的django被废除 |
from django import forms
class StoreForm(forms.Form):
s_name = forms.CharField(max_length = 32,label = "名称") #名称
s_address = forms.CharField() #地址
s_description = forms.CharField() # 描述
s_picture = forms.CharField() # 地址
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ form }}
<hr>
{{ form.as_p }}
<hr>
{{ form.as_ul }}
<hr>
{{ form.as_table }}
<hr>
{% for i in form %}
<div>
{{ i.label }} {{ i }}
</div>
{% endfor %}
</body>
</html>
在前端调用django form表单的概率太小了,大部分是使用form进行后端校验,校验的时候必须保证前端表单的name属性和form的字段名是对应的。
(二)校验的流程
1、在表单当中定义校验规则,规则定义在字段的validator参数上,来源于django.core.validators
from django import forms
from django.core import validators #校验来与于这个方法
class StoreForm(forms.Form):
s_name = forms.CharField(max_length = 32,label = "名称",validators = (
validators.RegexValidator(r"\w{6,8}","用户名不合法"), #只是一个长度和类型的校验
)) #名称,validators参数需要一共元组类型的参数,所以单元素需要加逗号
s_address = forms.CharField() #地址
s_description = forms.CharField() # 描述
s_picture = forms.CharField() # 地址
2、校验的时候
-
首先绑定请求的数据到表单实例
-
使用is_validate方法进行校验
-
如果校验成功,数据使用data方法查看
-
如果校验失败使用errors方法查看失败提示
def storeforms(request):
form = StoreForm()
if request.method == "POST":
store_data = StoreForm(request.POST)
if store_data.is_valid():#如果校验成功,就返回True,否再False
print(store_data.data) #校验成功后的数据,字典格式
else:
print(store_data.errors) #校验失败后的错误提示
return render(request,"forms.html",locals())
(三)自定义校验
from django import forms
from django.core import validators #校验来与于这个方法
#基于面向对象,编写类,利用构造函数和__call__魔术方法编写
class OurValid:
def __init__(self,message):
self.message = message
def __call__(self, value):
if value in ["admin","dmin","min","in","n"]:
raise validators.ValidationError(self.message)
#基于函数直接编写
def our_valid(value):
if value in ["admin", "dmin", "min", "in", "n"]:
raise validators.ValidationError("用户名不合适")
#在form类当中,基于clean_字段名编写
class StoreForm(forms.Form):
s_name = forms.CharField(max_length = 32,label = "名称",validators = (
validators.RegexValidator(r"\w{6,8}","用户名不合法"), #只是一个长度和类型的校验
our_valid
)) #名称,validators参数需要一共元组类型的参数,所以单元素需要加逗号
s_address = forms.CharField() #地址
s_description = forms.CharField() # 描述
s_picture = forms.CharField() # 地址
def clean_s_address(self):
s_address = self.cleaned_data.get("s_address") #cleaned_data指的是校验过的数据
if s_address in ["张家口"]:
raise validators.ValidationError("张家口一年刮风两次,一次半年")
五、Django会话技术
Django的会话技术和Flask会话技术都是采用cookie和session技术,原理上是一致的。操作方法上十分相似。
(一)cookie操作
1. 设置
还是设置在响应上。
def views_function(request):
response = render_to_response("index.html")
response.set_cookie("user_id","1")
return response
2. 获取
def views_function(request):
user_id = request.COOKIES.get("user_id") #获取cookie
response = render_to_response("index.html")
response.set_cookie("user_id","1")
return response
3. 删除
def views_function(request):
user_id = request.COOKIES.get("user_id")
response = render_to_response("index.html")
response.set_cookie("user_id","1")
response.delete_cookie("user_id") 删除cookie
return response
(二)session操作
session还是一个类字典对象
1. 设置
2. 获取
3. 删除
def session_function(request):
request.session["user_id "] = 1 #设置
user_id = request.session.get("user_id") #获取
del request.session["user_id "] #删除