python-44-Form自定制验证

241 阅读2分钟

1.app02/views

from django.shortcuts import render,HttpResponse,redirect
from django import forms
from django.forms import fields,widgets

class TestForm(forms.Form):
    user= fields.CharField(
        required=True,
        max_length=12,
        min_length=3,
        error_messages={},
        # widget=widgets.Textarea()
        #这里可以自定义属性。。。。。
        widget=widgets.TextInput(attrs={'n':123}),#定制生成的html插件
        label='用户名',
        initial='请输入用户名',#设置默认值
        help_text='请按照规则输入',
        show_hidden_initial=False,
        #validators=[],
        #disabled=True,#无法编辑
        label_suffix=':'

    )
    age=fields.IntegerField(
        label='年龄',
        max_value=12,
        min_value=5,
        error_messages={
            'max_value':'太大了',
            'min_value':'太小了'
        }
    )

    email=fields.EmailField(
        label='邮箱'
    )
    img=fields.FileField()
    #TypedChoiceField 可以帮助做数据转化
    city=fields.TypedChoiceField(
        #做数据类型转换
        coerce=lambda x:int(x),
        choices=[(1,'xiaoming'),(2,'fengfeng'),(3,'xiaohong')],
        initial=2
    )
    bobby=fields.MultipleChoiceField(
        choices=[(1,'game'),(2,'chifan'),(3,'daqiang')],
        initial=[1,2]
    )
    #显示文件路径
    xoo=fields.FilePathField(
        path='app01'
    )
    #单选的两种写法
    # xdb =fields.CharField(
    #     widget=widgets.Select(choices=[(1,'game'),(2,'chifan'),(3,'daqiang')])
    # )
    # xdb=fields.ChoiceField(
    #     choices=[(1,'game'),(2,'chifan'),(3,'daqiang')]
    # )
    #多选只有这一种写法
    # xdb=fields.MultipleChoiceField(
    #     #可以自定制属性
    #     widget=widgets.SelectMultiple(attrs={'class':'c1'}),
    #     choices = [(1, 'game'), (2, 'chifan'), (3, 'daqiang')]
    # )
    # xdb=fields.ChoiceField(
    #     widget=widgets.CheckboxInput(),
    #     label='是否同意啪啪'
    # )
    # xdb=fields.MultipleChoiceField(
    #     initial=[2],
    #     choices=[(1,'上海'),(2,'北京')],
    #     widget=widgets.CheckboxSelectMultiple()
    #
    # )

    xdb=fields.ChoiceField(
        choices=[(1,'上海'),(2,'北京')],
        initial=2,
        widget=widgets.RadioSelect
    )

# Create your views here.

def test(req):
    if req.method=="GET":
        obj=TestForm()
        #渲染成html
        txt="<input type='text'/>"
        from  django.utils.safestring import mark_safe
        txt=mark_safe(txt)

        return render(req,'test.html',{'obj':obj,'txt':txt})
    else:
        #req.POST 相当于一个大字典
        obj=TestForm(req.POST,req.FILES)
        obj.is_valid()
        print(obj.cleaned_data)
        return render(req, 'test.html', {'obj': obj})
from app01 import models
#第二种方式更新(不推荐)
from django.forms.models import ModelChoiceField

class LoveForm(forms.Form):
    price = fields.IntegerField()
    user_id = fields.IntegerField(

        #widget=widgets.Select(choices=[(0,'alex'),(1,'liuran'),(2,'songxinran'),])
        widget=widgets.Select()
    )

    user_id2=ModelChoiceField(
        queryset=models.UserInfo.objects.all(),
        #更改value,默认是主键
        to_field_name='username'

    )


    #需要添加init执行更新
    def __init__(self,*args,**kwargs):
        super(LoveForm,self).__init__(*args,**kwargs)
        #super必须在self.fields的上面
        self.fields['user_id'].widget.choices=models.UserInfo.objects.values_list('id','username')


def love(req):
    #此时数据库中的数据未被更新
    list111 = models.UserInfo.objects.values_list('id', 'username')
    print(list111)
    obj=LoveForm()
    return render(req,'love.html',{'obj':obj})

from django.core.exceptions import NON_FIELD_ERRORS,ValidationError
class AjaxForm(forms.Form):
    username = fields.CharField()
    user_id = fields.IntegerField(
        widget=widgets.Select(choices=[(0,'alex'),(1,'liuran'),(2,'songxinran'),])
    )
    #自定义方法
    # 先进行正则表达式检测,成功后运行clean_%s方法
    def clean_username(self):
        # 检测数据库中是否存在,防止重名
        v = self.cleaned_data['username']
        if models.UserInfo.objects.filter(username=v).count():
            #整体错了
            #详细错误信息
            raise ValidationError('用户名已存在')
        return v

        return self.cleaned_data['username']

    def clean_user_id(self):
        return self.cleaned_data['user_id']
    #此时已经所有字段验证成功
    #联合字段检测
    def clean(self):
        value_dict=self.cleaned_data
        v1=value_dict.get('username')
        v2=value_dict.get('user_id')
        print('user_id==****************************',v2)
        if v1=='root' and v2==1:
            raise ValidationError('整体错误信息')
        return self.cleaned_data



import json
def ajax(req):
    if req.method=="GET":
        obj = AjaxForm()
        return render(req,'ajax.html',{'obj':obj})
    else:
        ret={'status':999,'message':None}
        obj=AjaxForm(req.POST)
        if obj.is_valid():
            print(obj.cleaned_data)
            #ajax不跳转.....
            #跳转到百度
            #return redirect('http://www.baidu.com')
            ret['status']=1000
            return HttpResponse(json.dumps(ret))
        else:
            print(obj.errors)
            from django.forms.utils import ErrorDict
            print(obj.errors.as_ul())
            print(obj.errors.as_json())
            print(obj.errors.as_data())
            '''
            {
                __all__:[],
                username:[]
            }
            '''



            ret['message']=obj.errors
            #错误信息显示在页面上
            return HttpResponse(json.dumps(ret))
'''
-form表单(验证,保留上次内容)
-Ajax(验证:无序上次内容)
    -返回HttpResponse
    -前段:跳转或错误信息
'''

2.ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax</title>
</head>
<body>
<form id="fm" action="/ajax/" method="post">
    {% csrf_token %}
    {{ obj.as_p }}
    <input type="button" value="Ajax提交" id="btn">
</form>
<script src="/static/jquery-3.1.1.js"></script>
<script>
    $(function () {
        $('#btn').click(function () {
            $.ajax({
                url:'/ajax/',
                type:'POST',
                data:$('#fm').serialize(),
                dataType:'JSON',
                success:function (arg) {
                    if (arg.status==1000){
                        window.location.href="http://www.baidu.com"
                    }

                    console.log(arg);
                }
            })
        })
    })
</script>
</body>
</html>