zoukankan      html  css  js  c++  java
  • Dango生命周期回顾与forms组件

    Django请求生命周期

    前后端数据交换

    一般的编码格式

    1、urlencoded
    2、formdata
    3、application/json

    form表单编码格式

    form表单默认的编码格式是urlencoded不支持发文件(只能把文件名发过去)
    它所对应数据格式 username=jason&password=123

    formdata

    request.POST只能解析urlencoded数据格式的数据
    formdata django会帮你把文件数据取出来 放入request.FILES里面 专门用来传文件的

    .html
    <form action="" method="post" enctype="multipart/form-data">  //注意enctype
        {% csrf_token %}
        username: <input type="text" name="username"><br>
        password: <input type="password" name="password"><br>
        img: <input type="file" name="myfile"><br>
        <input type="submit" value="提交">
    
    </form>
    
    view.py
    file_obj = request.FILES.get('myfile')
            print(file_obj.name)  # 查看当前文件对象的文件名
            with open(file_obj.name,'wb') as f:
                for line in file_obj:
                    f.write(line)
    

    AJAX

    Ajax默认提交的编码格式也是urlencoded
    当用ajax传输json格式的数据时候 django不会做任何处理
    数据以二进制形式放在request.body中 你可以手动解码加反序列化拿到对应的字典格式数据

    bytes_str = request.body
            res = json.loads(bytes_str.decode('utf-8'))
            print(res,type(res))
    

    jax发送文件 利用js内置的FormData对象

    <input type="file" name="myfile" id="d2">
    <button id="d1">点我</button>
    
    $('#d1').click(function () {
            // 如果用ajax发送文件 需要使用内置对象FormData
            var formData = new FormData();  // 生成一个内置对象
            // 内置对象formdata既可以传普通的键值对,也可以传文件
            formData.append('name','jason');  // 普通键值对
            formData.append('password','123');
            // 传文件
            var fileObj = $('#d2')[0].files[0];  // 先获取标签对象 转成原生js对象 通过内置的files方法拿到所有的文件对象列表 然后去索引0拿到文件对象
            formData.append('myfile',fileObj);
            $.ajax({
                url:'',  // 不写默认朝当前页面所在的url地址提交
                type:'post',
                // 注意ajax在发送文件的时候 需要你手动指定两个特殊的参数,这两个必须写
                contentType:false,  // 不要用任何编码 使用我formdata自带的编码即可
                processData:false,  // 浏览器不要处理我的数据 是什么就什么
                data:formData,
                success:function (data) {
                    alert(data)
                }
    
            })
        })
    

    forms组件

    forms组件的3个过程

    1.前端渲染展示页面 获取用户输入 >>> 渲染页面
    2.将数据发送给后端进行数据的合法性校验 >>> 数据校验
    3.将不合法的提示信息展示给用户看 >>> 展示提示信息
    关于数据的校验
    1.前端
    2.后端
    数据的校验前端可以没有,但是后端一定要做!!!

    自己写一个前后端校验的例子

    .html
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        username: <input type="text" name="username">
        <span>{{ back_dic.flag }}</span>
        <br>
        password: <input type="password" name="password">
        <span>{{ back_dic.msg }}</span>
        <br>
        img: <input type="file" name="myfile"><br>
        <input type="submit" value="提交">
    </form>
    
    views.py
    def index(request):
        if request.method == 'POST':
            # file_obj = request.FILES.get('myfile')
            # print(file_obj.name)
            # print(request.body)
            back_dic = {"flag":'',"msg":''}
            username = request.POST.get('username')
            password = request.POST.get('password')
            if not username:
                back_dic['flag'] = "账户不能为空"
            if len(password) < 6:
                back_dic['msg'] = "密码太短"
        return render(request,"inddex.html",locals()) //将函数内的名称空间全部传过去
    

    forms组件校验数据

    1.校验数据

    forms组件的校验数据的使用
    1.定义一个继承forms.Form一个类
    from django import forms
    class MyForm(forms.Form):
    	username = forms.CharField(max_length=6)  # username最长只能是6位
    	password = forms.CharField(max_length=8,min_length=3)  # password最长8位 最短3位
    	email = forms.EmailField()  # email接受的数据必须符合邮箱格式
    
    完整版
    # 使用forms组件第一步需要你手动写一个类 并且要继承forms.Form
    from django import forms
    from django.forms import widgets   # 当你用forms点widgets点不出来的时候 自己手动导入一下
    from django.core.validators import RegexValidator
    class MyForm(forms.Form):
        username = forms.CharField(max_length=6,label='用户名',initial='我是最帅的',error_messages={
                                                                    'max_length':'用户名最长6位',
                                                                    'required':'用户名不能为空'
    
        })  # username最长只能是6位
        password = forms.CharField(max_length=8,min_length=3,label='密码',
                                   widget=widgets.PasswordInput(attrs={'class':'form-control c1',})
    
                                   )  # password最长8位 最短3位
        confirm_password = forms.CharField(max_length=8, min_length=3, label='确认密码',
                                   widget=widgets.PasswordInput(attrs={'class': 'form-control c1', })
    
                                   )  # password最长8位 最短3位
        phone = forms.CharField( validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],)
        email = forms.EmailField(label='邮箱',error_messages={
                                                'required':'邮箱不能为空',
                                                'invalid':'邮箱格式不正确'
        })  # email接受的数据必须符合邮箱格式
    
        forms组件中所有的字段默认都是必填的(不能为空)
        在数据都满足forms组件校验规则的情况下 多传的数据不校验 没有关系
        
    
    
        gender = forms.fields.ChoiceField(
            choices=((1, "男"), (2, "女"), (3, "保密")),
            label="性别",
            initial=3,
            widget=forms.widgets.RadioSelect()
        )
        hobby = forms.ChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
            label="爱好",
            initial=3,
            widget=forms.widgets.Select()
        )
    
        hobby1 = forms.MultipleChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
            label="爱好",
            initial=[1, 3],
            widget=forms.widgets.SelectMultiple()
        )
    
        keep = forms.ChoiceField(
            label="是否记住密码",
            initial="checked",
            widget=forms.widgets.CheckboxInput()
        )
    
    2.给forms组件传参数 (字典的显示)
    	obj = views.MyForm({'username':'egondsb','password':'12','email':'123@qq.com'})
    3.查看数据是否完全合法
    	obj.is_valid()
    4.查看所有校验通过的数据
    	obj.cleaned_data
    	{'email': '123@qq.com'}
    5.查看所有没有通过的数据
    	obj.errors
    	"""
    	{
    	'username': ['Ensure this value has at most 6 characters (it has 7).'], 
    	'password': ['Ensure this value has at least 3 characters (it has 2).']}
    	"""
    

    2.渲染标签

    forms组件只能帮你渲染 获取用户输入(输入框 选择框 下拉框...)的标签
    提交按钮也得自己写
    form表单取消前端校验功能

    	<form action="" method="post" novalidate>	
    

    forms组件当前端输入的信息不合法的时候 页面上的数据保留不会刷新 这样方便用户修改

    3.展示提示信息

    	{% for foo in form_obj %}
            <p>
            {{ foo.label }}{{ foo }}
             <span>{{ foo.errors.0 }}</span>
             </p>
    	{% endfor %}
    

    forms组件的钩子函数

    # 局部钩子
    def clean_username(self):
    # 用户名中不能有666
    	username = self.cleaned_data.get('username')
    	if '666' in username:
    		self.add_error('username','光喊666是不行的')
    	return username
    		
    # 全局钩子
    def clean(self):
    	# 获取密码和确认密码比对
    	password = self.cleaned_data.get('password')
    	confirm_password = self.cleaned_data.get('confirm_password')
    	if not password == confirm_password:
    		self.add_error('confirm_password','两次密码不一致')
    	return self.cleaned_data
    

    django代码测试

    import os
    import sys
    
    if __name__ == "__main__":
    	os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day66.settings")
    	import django
    	django.setup()
    		  
    	from app01 import models
    	print(models.Userinfo.objects.all())
    
  • 相关阅读:
    关于浏览器cookie的详解
    浏览器渲染帧
    Vue3中关于diff的优化
    JS报错 Cannot set property 'display' of undefined问题
    vue选项卡 ,循环数据点击改变class,并初始循环中的第一个为选中状态class
    Nuxt中引入elementUI
    jq 获取节点 改变元素class的显示、隐藏
    vue监听滚动条
    Nuxt中引入iconfont图标
    vue导航点击切换 2.0
  • 原文地址:https://www.cnblogs.com/huanghongzheng/p/11226039.html
Copyright © 2011-2022 走看看