首页 > 代码库 > Django之Form组件

Django之Form组件

1.内容回顾

1)Django请求生命周期

HTTP请求->WSGI服务器(WEB服务网关接口)->中间件->url(路由系统)->view(匹配视图函数)->views从model取数据->从前端拿模板->模板渲染给用户返回一个大的字符串(网页内容)    

2)Session是什么?

Session:是保存在服务端的数据,当用户登录时,服务端生成随机字符串给客户端的浏览器,浏览器写到cookie里,服务器端把随机字符串保存起来,服务端的随机字符串和客户端的cookie里的随机字符串一一对应。

3)XSS是什么?

XSS:跨站脚本攻击
        举例:评论(while循环,alert),
        防止XSS(1.客户端提交什么数据,以安全的形式查看,当作字符串让用户访问,2.用户提交时过滤关键字,如script)

4)CSRF-POST(银行的例子) 两个网站

CSRF:跨站请求伪造(POST请求)
        不仅发送数据,还要发送随机字符串(上一次POST请求获取到的)

2.今日内容:

 Form组件

Form作用有两个1.用户提交数据进行校验;2.保留上次输入内容

提交数据方式:1.Form提交;2.Ajax提交

1. 用户提交数据进行校验

- Form提交(刷新,失去上次内容)
a. LoginForm(Form)
字段名 = xxxx.xxField() # 本质就是验证规则,正则表达式
字段名 = xxxx.xxField() # 本质验证规则,正则表达式
字段名 = xxxx.xxField() # 本质验证规则,正则表达式
字段名 = xxxx.xxField() # 本质验证规则,正则表达式
b. obj = LoginForm(用户提交的数据,request.POST)

c. result = obj.is_valid() 进行校验 print(result)返回True 或者False

d. obj.cleaned_data:是一个字典,如果校验成功了,拿到正确的值

e. obj.errors:是一个对象,包含所有的错误信息

内部原理

技术分享
def login(request):
    if request.method == GET:
        return render(request, login.html)
    else:
        obj = LoginForm(request.POST)
        #is_valid
        """
        获取当前类所有的对象
        1.LoginForm实例化时,self.fields中
        self.fields={
            user:正则表达式,
            pwd:正则表达式,
        }
        2.循环self.fields,
            flag = True验证通过(用户名密码。。都输入正确)
            errors
            cleaned_data
            for k,v in self.fields.items():
                k是user,pwd
                v是:正则表达式
                input_value = request.POST.get(k):前端输入的值,写几个字段,就取谁
            正则表达式和input_value进行正则匹配(这里用的是match)
                flag = False
            return flag
        """
        if obj.is_valid():#如果正确
            print(obj.cleaned_data)#字典类型
            return redirect(http://www.baidu.com)
        else:
            print(obj.errors)
        return render(request, login.html, {obj:obj})
Form提交登录验证代码login函数
技术分享
def login(request):
                        if request.method == GET:
                            return render(request,login.html)
                        else:
                            obj = LoginForm(request.POST)
                            # is_valid
                            """
                            1. LoginForm实例化时,
                                self.fields={
                                    user: 正则表达式
                                    pwd: 正则表达式
                                }
                            2. 循环self.fields
                                  flag = True
                                  errors
                                  cleaned_data
                                  for k,v in self.fields.items():
                                    # 1. user,正则表达式
                                    input_value = request.POST.get(k)
                                    正则表达式和input_value
                                    flag = False
                                  return flag
                           """
                            if obj.is_valid():
                                print(obj.cleaned_data)
                            else:
                                print(obj.errors)
                            return render(request,login.html)
View Code
技术分享
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <h1>用户登录</h1>
    <form id="f1" action="/login/" method="POST">
        {% csrf_token %}
        <p>
            用户名:<input type="text" name="user" />{{ obj.errors.user.0 }}
        </p>
        <p>
            密码:<input type="password" name="pwd" />{{ obj.errors.pwd.0 }}
        </p>
        <input type="submit" value=http://www.mamicode.com/"提交">
        <a onclick="submitForm();">提交</a>    #onclick绑定事件
    </form>
    <script src=http://www.mamicode.com/"/static/jquery-1.12.4.js"></script>
    <script>
        function submitForm(){
            $(.c1).remove();    #把以前的错误信息都清除掉
            $.ajax({
                url:/ajax_login/,    
                type:POST,        #提交方式
                data:$(#f1).serialize(),    #找到f1标签,jQuery ajax - serialize() 方法,serialize() 方法通过序列化表单值,创建 URL 编码文本字符串。
                datatype:"JSON",                    #serialize()拼接字符串,  user=alex&pwd=456&csrf_token=bing
                success:function(arg){
                    console.log(arg);
                    if (arg.status){

                    }else{
                        $.each(arg.msg,function (index,value) {    循环把所有错误信息输出index,value(也就是key和value )
                            console.log(index,value);
                            var tag = document.createElement(span);    #创建节点:
                            tag.innerHTML = value[0];        #获取第一个错误信息,innerHTML 给节点添加html代码:
                            tag.className = c1;
                            $(#f1).find(input[name="+ index +"]).after(tag);    #在span标签的后面
                            //‘  input[name="  ‘ + index + ‘  "]  ‘==input[name=user]
                        })
                    }
                }
            })
        }
    </script>

</body>
</html>
前端login.html代码

前端涉及知识点:

1) createElement(标签名) :创建一个指定名称的元素。

例:var tag=document.createElement(“input")
tag.setAttribute(‘type‘,‘text‘);

2)data:$(‘#f1‘).serialize()  serialize() 方法可以操作已选取个别表单元素的 jQuery 对象,比如 <input>, <textarea> 以及 <select>。

不过,选择 <form> 标签本身进行序列化一般更容易些:
打包user,pwd,csrf_token,拼接字符串

咱们写的字典也会变成字符串
请求体:‘user=alex&pwd=456&csrf_token=bing‘

注意:render的本质还是返回HttpResponse(字符串)

return render():
def render(request, template_name, context=None, content_type=None, status=None, using=None):
"""
Returns a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)

 

2.- Ajax提交(不刷新,上次内容自动保留)

PS: Ajax提交(页面不刷新,数据不清空) > Form提交(Form表单一刷新,页面刷新,输入的数据都会清空)    总结:

class Foo(Form):
            字段 = 正则表达式  :是否可以为空,最长,最短
            字段 = 自定义正则表达式
                   1. 常用
                        charField 
  ... 定义正则表达式 参数: 验证:(本质上都是正则表达式) required error_messages 生成HTML标签: widget
=widgets.Select, ******** 用于指定生成怎样的HTML,select,text,input/. label=用户名, # obj.t1.label disabled=False, # 是否可以编辑 label_suffix=--->, # Label内容后缀 initial=666, # 无用,猜测有问题应该在input框中显示默认值 help_text=。。。。。。, # 提供帮助信息

- 生成HTML标签
- 保留上次输入内容

IntegerField继承Field
CharField 继承Field
EmailField继承 CharField
URLField继承CharField

t4 = fields.URLField()
t5 = fields.SlugField() #字母数字下划线,内部也是正则表达式
t6 = fields.GenericIPAddressField()
t7 = fields.DateTimeField()
t8 = fields.DateField()
技术分享
def ajax_login(request):
    # request.POST.get()
    import json
    ret = {status:True,msg:None}
    obj = LoginForm(request.POST)
    if obj.is_valid():
        print(obj.cleaned_data)#{user: alex, pwd: alexalexalexalexalex}
    else:
        print(obj.errors)#obj.errors,是一个 对象(无序列表)
        ret[status] = True
        ret[msg] = obj.errors
        # error = json.dumps(obj.errors)
        # print(error)
    v = json.dumps(ret)
    print(v)#输入错误:输出{"status": true, "msg": {"user": ["This field is required."], "pwd": ["This field is required."]}}
    #输入正确:{"status": true, "msg": null}
    return HttpResponse(v)#提交错误时,<ul class="errorlist"><li>user<ul class="errorlist"><li>This field is required.</li></ul></li><li>pwd<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
#ajax提交
# {user: alex, pwd: alexalexalexalexalex}
    # return render()
AJAX提交方式(ajax_login函数)
技术分享
    <script src=http://www.mamicode.com/"/static/jquery-1.12.4.js"></script>
    <script>
        function submitForm(){
            $(.c1).remove();
            $.ajax({
                url:/ajax_login/,
                type:POST,
                data:$(#f1).serialize(),
                datatype:"JSON",
                success:function(arg){
                    console.log(arg);
                    if (arg.status){

                    }else{
                        $.each(arg.msg,function (index,value) {
                            console.log(index,value);
                            var tag = document.createElement(span);
                            tag.innerHTML = value[0];
                            tag.className = c1;
                            $(#f1).find(input[name="+ index +"]).after(tag);
                        })
                    }
                }
            })
        }
    </script>
前端jQuery+AJAX代码

Form组件之常用字段和参数

技术分享
Field
    required=True,               是否允许为空
    widget=None,                 HTML插件
    label=None,                  用于生成Label标签或显示内容
    initial=None,                初始值
    help_text=‘‘,                帮助信息(在标签旁边显示)
    error_messages=None,         错误信息 {required: 不能为空, invalid: 格式错误}
    show_hidden_initial=False,   是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
    validators=[],               自定义验证规则
    localize=False,              是否支持本地化
    disabled=False,              是否可以编辑
    label_suffix=None            Label内容后缀
Field

 

Django之Form组件