day03 ajax删除操作、form组件
回顾
发送请求的途径:
-
直接在地址栏输入地址 get
-
form表单提交 method='' post/get
-
a标签 get
-
ajax
ajax
使用js的技术与服务器进行异步交互。
特点:
-
异步
-
局部刷新
-
传输的数据量小
使用
// 导入jquery.js
上传文件
html上传
前提条件:必须确保有csrftoken的cookie
-
使用{% csrf_token %}的标签
-
给视图函数加上ensure_csrf_cookie的装饰器
ajax通过django的csrf的校验:
-
给data中添加csrfmiddlewaretoken
-
给headers中添加x-csrftoken的请求头
推荐的方式:导入文件 + 使用{% csrf_token %}
csrf中间件的流程:
-
process_request
从cookie中获取了csrftoken的值将该值放入request.META中
-
process_view
-
如果是 直接接受该请求,不做csrf的校验
-
不是 则进行csrf的校验
-
csrf_token = request.META.get('CSRF_COOKIE') # cookie中csrftoken的值
-
request_csrf_token = ""
-
请求方式是post,尝试从request.POST中获取csrfmiddlewaretoken的值
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
-
如果request_csrf_token = "",再尝试从请求头中获取X-CSRFTOKEN的值
request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')
-
比较csrf_token和request_csrf_token,成功则通过,不成功则拒绝
-
判断视图是否使用了csrf_exempt的装饰器,使用了就不再进行csrf的校验
-
判断请求方式是否是get head potions trace:
小案例 ajax发送请求进行删除操作
删除 {
if (willDelete) {
$.ajax({
url: $(this).attr('url'),
type: 'get',
success: (data) => {
if (data.status === 200) {
$(this).parent().parent().remove()
swal("数据已成功删除", {
icon: "success",
} else {
swal("删除失败!", {
icon: "error",
} else {
swal("已取消",{
icon: "info",
})" _ue_custom_node_="true">
def delete(request, name, pk):
print(name, pk)
# 找到要删除的对象 进行删除
cls = getattr(models, name.title())
if not cls:
return HttpResponse('检测表名')
ret = cls.objects.filter(pk=pk)
if ret:
ret.delete()
else:
return HttpResponse('要删除的数据不存在')
# 返回重定向
# return redirect(name) # redirect里可以直接写上url的name
# return HttpResponse('ok')
# return HttpResponse(reverse(name)) # 返回重定向的地址,让ajax通过前端去刷新页面
return JsonResponse({'status': 200})
form组件
定义:
from django import forms
class RegForm(forms.Form):
user = forms.CharField(label='用户名')
pwd = forms.CharField(label='密码')
使用:
def reg2(request):
form_obj = RegForm() # 空的form
if request.method == 'POST':
# 对提交的数据做校验
form_obj = RegForm(request.POST) # 包含用户提交的数据的form
if form_obj.is_valid(): # 对数据进行校验
# 校验成功
return HttpResponse('注册成功')
return render(request, 'reg2.html', locals())
模板
// 一次性生成所有的标签{% csrf_token %}
{{ form_obj.as_p }}注册// 单独的生成input框
{# novalidate 不在前端做校验#}{% csrf_token %}{{ form_obj.user.label }}{{ form_obj.user }} {{ form_obj.user.errors.0 }}
{{ form_obj.pwd.label }}{{ form_obj.pwd }} {{ form_obj.user.errors.0 }}
{# {{ form_obj.errors }}#}注册
MultipleChoiceField{{ form_obj.as_p }} # 一次性生成所有的input框
{{ form_obj.user }} # 该字段的input框
{{ form_obj.user.label }} # 该字段提示的信息
{{ form_obj.user.id_for_label }} # 该字段的input框的id
{{ form_obj.user.errors}} # 该字段的所有错误
{{ form_obj.user.errors.0}} # 该字段的第一个错误
{{ form_obj.errors }} # 所有字段的错误
常用字段
CharField # 文本输入框
ChoiceField # 单选 默认是select
MultipleChoiceField # 多选 默认是select
常用参数
initial = "hina" # 默认值
choices # 用户选择的数据
error_messages # 自定义错误信息
widget # 插件 修改input框的类型
required=True # 是否必填
disabled=True # 是否禁填
validators # 校验器
校验器
-
定义函数
from django.core.exceptions import ValidationError
def check_name(value):
# 不符合校验规则
if 'hina' in value:
raise ValidationError('hina的名字不合适')
# 符合校验不做任务操作
-
使用内置的校验器
from django.core.validators import RegexValidator
phone = forms.CharField(validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式不正确')])
钩子函数
-
局部钩子
# 一定要写在类中
def clean_user(self): # 局部钩子
# 不符合校验规则 抛出异常
value = self.cleaned_data.get('user')
if 'hina' in value:
raise ValidationError('hina的名字不合适')
# 符合校验规则 返回该字段的值
return value
-
全局钩子
def clean(self): # 全局钩子
pwd = self.cleaned_data.get('pwd')
repwd = self.cleaned_data.get('repwd')
if pwd != repwd:
# 不符合校验规则 抛出异常
# 将错误信息加入到某个字段中
self.add_error('repwd', '两次密码不一致!!!')
raise ValidationError('两次密码不一致')
# 符合校验规则 返回该字段的值
return self.cleaned_data
is_valid()的流程:
-
执行一个full_clean方法
-
定义了一个错误字典和 cleaned_data={} # 存已经经过校验的数据的字典
-
执行self._clean_fields()
循环所有字段
对一个字典进行内置校验、校验器校验、局部钩子校验
校验不通过,将该字段以及对应的错误信息加入该字典
所有校验通过,self.cleaned_data有该字段和该字段的值
-
执行全局钩子