Python--day66(前后台数据交互的数据编码,forms组件)

1. 前后台数据交互的数据编码

1.1 前后端数据交互的数据编码格式

1.urlencoded 
2.formdata 
3.application/json

1.2 form表单、ajax发送json格式的数据和发送文件

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


当form表单的编码设置为
enctype="multipart/form-data"
form-data django会帮你把文件数据取出来 放入request.FILES里面 专门用来传文件的
Ajax默认提交的编码格式也是urlencoded 

ajax发送json格式数据:当用ajax传输json格式的数据时候,设置编码为:contentType:'application/json',
此时django不会做任何处理 数据以二进制形式放在request.body中 你可以手动解码加反序列化拿到对应的字典格式数据 ajax发送文件 利用js内置的FormData对象
Ajax发送json格式数据
     $.ajax({
            url:'',  // 不写默认朝当前页面所在的url地址提交
            type:'post',
            contentType:'application/json',
            data:JSON.stringify({'name':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}),
            success:function (data) {
                alert(data)
            }
        })
    
Ajax发送文件
    $('#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)
            }

        })
    })
    

 

2. forms组件

2.1 form组件校验数据

两种校验方式

# 1. 自己创建一个test.py脚本
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "s8day66.settings")
    import django
    django.setup()

    from app01 import models
    print(models.Userinfo.objects.all())

# 2. 通过 Python Console来测试(具体参见下面) 
# 1. 定义一个继承forms.Form一个类
from django import forms

class MyForm(forms.Form):
    username = forms.CharField(max_length=8)
    password = forms.CharField(max_length=8, min_length=3)    
    email = forms.EmailField()
    
# 2. 给form组件传参数(按照字典的形式)
obj = views.MyForm({'username':'wangyong123','password':'12','email':'[email protected]'})

# 3. 查看数据是否完全合法
obj.is_valid()

# 4. 查看所有校验通过的数据
obj.cleaned_data

# 5. 查看所有没有通过的数据
obj.errors
# 上面示例运行具体过程
from app01 import views
obj = views.MyForm({'username':'wangyong123','password':'12','email':'[email protected]'})
obj.is_valid()
False
obj.cleaned_data
{'email': '[email protected]'}
obj.errors
{'username': ['Ensure this value has at most 8 characters (it has 11).'], 'password': ['Ensure this value has at least 3 characters (it has 2).']}

forms组件中所有的字段默认都是必填的(不能为空)
在数据都满足forms组件校验规则的情况下 多传的数据不校验 没有关系

 

2.2 form组件渲染页面

def register(request):
    form_obj = MyForm()
    return render(request, 'register.html', locals())

 

{# novalidate代表取消前端校验 #}
<form action="" method="post" novalidate>

 

第一种方式:

Python--day66(前后台数据交互的数据编码,forms组件)_第1张图片

 

第二种方式:

 Python--day66(前后台数据交互的数据编码,forms组件)_第2张图片

 

 第三种方式:

Python--day66(前后台数据交互的数据编码,forms组件)_第3张图片

 

2.3 form组件提示报错信息

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

 

Python--day66(前后台数据交互的数据编码,forms组件)_第4张图片

 

 2.4 form组件中常用参数

max_length = 6          # 最大长度为6
label='用户名'           # 设置标签名称,默认为字段名首字母大写
initial='我是最帅的'      # 设置默认值
error_messages = {
  invalid:'邮箱格式不正确''required':'用户名不能为空'    
}
widget = widgets.PasswordInput()   # 设置密码密文
# 用正则匹配条件
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],

······

【正则匹配参考链接】:http://tool.chinaz.com/regex/?qq-pf-to=pcqq.group

2.5 钩子函数

钩子函数是用来校验输入的数据是否是正确的,前提是已经符合在class类中的参数的校验才能进入钩子函数,钩子函数写在创建类的下面。

钩子函数分为局部钩子和全局钩子: 局部钩子是指的是对一个字段进行校验,全局钩子指的是对两个及两个以上的钩子进行校验。

    # 局部钩子
    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 password != confirm_password:
            self.add_error('confirm_password', '两次密码必须一致')
        return self.cleaned_data

 

2.6 其他了解

# 单选radio值为字符串
    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()
    )
    # 多选
    hobbys = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )
    # 单选checkbox(默认记住密码)
    keep = forms.ChoiceField(
        label="是否记住密码",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )
    # 多选,含有默认选项的多选
    hobby2 = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )
了解(技多不压身)

 

你可能感兴趣的:(Python--day66(前后台数据交互的数据编码,forms组件))