zoukankan      html  css  js  c++  java
  • Django组件-forms组件

    forms组件

    一、校验字段功能

    针对一个实例:注册用户讲解。

    模型:使用django的auth_user表

    模板:register.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
    </head>
    <body>
    
    <form action="" method="post">
        {% csrf_token %}
        <div>
            <label for="user">用户名</label>
            <p><input type="text" name="user" id="user"></p>
        </div>
        <div>
            <label for="pwd">密码</label>
            <p><input type="password" name="pwd" id="pwd"></p>
        </div>
        <div>
            <label for="r_pwd">确认密码</label>
            <p><input type="password" name="r_pwd" id="r_pwd"></p>
        </div>
         <div>
            <label for="email">邮箱</label>
            <p><input type="email" name="email" id="email"></p>
        </div>
        <input type="submit">
    </form>
    
    </body>
    </html>

    视图函数:register

    class UserForm(forms.Form):  #校验规则
        user = forms.CharField(min_length=5,
                               error_messages={'required':'该字段不能为空'},
                               label='用户名',
                               widget=widgets.TextInput(attrs={'class':'input','id':'user'})
                               )
        pwd = forms.CharField(min_length=5,
                              error_messages={'required':'该字段不能为空'},
                              label='密码',
                              widget=widgets.PasswordInput(attrs={'class':'input','id':'pwd'})
    
                              )
        r_pwd = forms.CharField(min_length=5,
                                error_messages={'required': '该字段不能为空'},
                                label='确认密码',
                                widget=widgets.PasswordInput(attrs={'class': 'input','id':'r_pwd'})
                                )
        email = forms.EmailField(error_messages={'invalid':'邮箱格式错误','required': '该字段不能为空'},
                                 label='邮箱',
                                 widget=widgets.EmailInput(attrs={'class':'input','id':'email'})
                                 )
        #自定义错误,进行第二次过滤(局部钩子)
        def clean_user(self):
            val=self.cleaned_data.get('user')
            print(val)
            # user_obj = auth.authenticate(username=val)
            ret = User.objects.filter(username=val)
            print(ret)
            if not ret:    #数据库找不到这个用户
                return val
            else:
                raise ValidationError('用户已存在!')
        def clean_pwd(self):
            val=self.cleaned_data.get('pwd')
            if val.isdigit():
                raise ValidationError('密码不能是纯数字!')
            else:
                return val
        def clean_email(self):
            val=self.cleaned_data.get('email')
            if not val.endswith('163.com'):
                raise ValidationError('邮箱必须是163邮箱!')
            else:
                return val
        def clean(self):  #全局钩子,什么情况下都会执行
            pwd=self.cleaned_data.get('pwd')
            r_pwd=self.cleaned_data.get('r_pwd')
    
            if pwd and r_pwd:
                if pwd==r_pwd:
                    return self.cleaned_data
                else:
                    raise ValidationError('两次密码不一致!')
            else:
                return self.cleaned_data

    逻辑代码:

    def register(request):
        import json
        if request.method == 'GET':
            form = UserForm()
            return render(request, 'reg.html',locals())
        else:
            form = UserForm(request.POST)
            if form.is_valid():    #对数据进行校验
                user = form.cleaned_data.get('user')   #form.cleaned_data为一个字典,里面存储着符合条件的字段
                pwd = form.cleaned_data.get('pwd')    
                email = form.cleaned_data.get('email')
                user_obj = User.objects.create_user(username=user,password=pwd,email=email)
                auth.login(request, user_obj)
                return HttpResponse('OK')
            else:
                errors=form.errors  #form.errors为一个字典,键是错误的字段,值是相关的错误的信息
                return HttpResponse(json.dumps(errors))

    二、渲染标签功能

    方式一:

    <form action="" method="post">   //form表单和submit按钮需要自己写
        {% csrf_token %}
        {{ form.as_p }}
    
        <input type="submit">
    </form>

    方式二:

    <form action="" method="post" novalidate>
                    {% csrf_token %}
                    <p> 用户名 {{ form.user }}<span class="error">{{ errors.user.0 }}</span> </p>            //{{ form.user }}渲染出user的input标签
                    <p>密码 {{ form.pwd }}<span class="error">{{ errors.pwd.0 }}</span></p>
                    <p>确认密码 {{ form.r_pwd }}<span class="error">{{ errors.r_pwd.0 }}</span></p>
                    <p>邮箱 {{ form.email }}<span class="error">{{ errors.email.0 }}</span></p>
    
                    <input type="submit" class="btn btn-success pull-right">
                </form>

    方式三:

    <form action="" method="post" novalidate>
                    {% csrf_token %}
                    {% for field in form %}
                        <div class="form-group">
                            <label for="">{{ field.label }}</label>
                            {{ field }} <span class="error">{{ field.errors.0 }}</span>
    {#                        //{{ field }}为渲染出来的input标签#}
                            {% if field.label == "确认密码" %}
                               <span class="error">{{ g_error|default:"" }}</span>
                            {% endif %}
                        </div>
                    {% endfor %}
                    <input type="submit" class="btn btn-success pull-right">
                </form>

    三、显示错误与重置输入信息功能

    方式一:form表单操作

    视图:

    def reg(request):
        if request.method=="POST":
            print(request.POST)
            # 数据校验
            form=UserForm(request.POST)
            if form.is_valid():
                UserInfo.objects.create(**form.cleaned_data)
                return HttpResponse("OK")
            else:
                # print(form.cleaned_data)
                # print(form.errors) # {"user":["",]}
                # print(form.errors.get("user")[0]) # {"user":["",]}
                errors=form.errors
                if form.errors.get("__all__"):
                    g_error=form.errors.get("__all__")[0]
                return render(request, "reg.html",locals())
        else:
             form=UserForm()
             return render(request,"reg.html",locals())

    模板:

    <form action="" method="post" novalidate>
                    {% csrf_token %}
                    {% for field in form %}
                        <div class="form-group">
                            <label for="">{{ field.label }}</label>
                            {{ field }} <span class="error">{{ field.errors.0 }}</span>
    {#                        //{{ field }}为渲染出来的input标签#}
                            {% if field.label == "确认密码" %}
                               <span class="error">{{ g_error|default:"" }}</span>
                            {% endif %}
                        </div>
                    {% endfor %}
                    <input type="submit" class="btn btn-success pull-right">
                </form>

    方式二:Ajax操作

    视图:

    def register(request):
        import json
        if request.method == 'GET':
            form = UserForm()
            return render(request, 'reg.html',locals())
        else:
            form = UserForm(request.POST)
            if form.is_valid():    #对数据进行校验
                user = form.cleaned_data.get('user')   #form.cleaned_data为一个字典,里面存储着符合条件的字段
                pwd = form.cleaned_data.get('pwd')
                email = form.cleaned_data.get('email')
                user_obj = User.objects.create_user(username=user,password=pwd,email=email)
                auth.login(request, user_obj)
                return HttpResponse('OK')
            else:
                errors=form.errors  #form.errors为一个字典,键是错误的字段,值是相关的错误的信息
                return HttpResponse(json.dumps(errors))

    模板:

    {% for field in form %}
        <div class="group">
            <label for="" class="label">{{ field.label }}</label>
            {{ field }}<span class="error"></span>
        </div>
    {% endfor %}
    <div class="group">
        <input type="submit" class="button" value="注册" id="zhuce">
    </div>
    <script src="/static/js/jquery.js"></script>
    <script>
        $('#zhuce').click(function () {
            $.ajax({
                url:'/register/',
                type:'post',
                data:{
                    user:$('#user').val(),
                    pwd:$('#pwd').val(),
                    r_pwd:$('#r_pwd').val(),
                    email:$('#email').val()
                },
                success:function (response) {
                    if(response=='OK'){
                        location.href='/books/'
                    }
                    else{
                        $.each(JSON.parse(response),function (i,j) {
                            if(i=='user'){
                                $('#user').next().html(j[0])
                            }if (i=='pwd'){
                                $('#pwd').next().html(j[0])
                            }if (i=='r_pwd'){
                                $('#r_pwd').next().html(j[0])
                            }if (i=='email'){
                                $('#email').next().html(j[0])
                            }if(i=='__all__'){
                                $('#r_pwd').next().html(j[0])
                            }
                        });
    
                    }
                }
            })
        });
    </script>

    或者更简单一些:

    视图:

    def register(request):
        from django.http import JsonResponse
        if request.method == 'GET':
            form = UserForm()
            return render(request, 'reg.html',locals())
        else:
            form = UserForm(request.POST)
            res = {'user':None,'err_msg':''}
            if form.is_valid():    #对数据进行校验
                user = form.cleaned_data.get('user')   #form.cleaned_data为一个字典,里面存储着符合条件的字段
                res['user'] = user
                pwd = form.cleaned_data.get('pwd')
                email = form.cleaned_data.get('email')
                user_obj = User.objects.create_user(username=user,password=pwd,email=email)
                auth.login(request, user_obj)
            else:
                errors=form.errors  #form.errors为一个字典,键是错误的字段,值是相关的错误的信息
                res['err_msg'] = errors
            return JsonResponse(res)   #JsonResponse对字典进行序列化,底层封装了HttpResponse,相关信息Ajax接收后会自动反序列化,不需要再人为的反序列化.

    模板:

    <script src="/static/js/jquery.js"></script>
    <script>
        $('#zhuce').click(function () {
            $.ajax({
                url: '/register/',
                type: 'post',
                data: {
                    user: $('#user').val(),
                    pwd: $('#pwd').val(),
                    r_pwd: $('#r_pwd').val(),
                    email: $('#email').val()
                },
                success: function (response) {                             //ajax已经自动将序列化的字典进行了反序列化
                    if (response.user) {
                        location.href = '/books/'
                    }
                    else {
                        $('.error').html('');
                        $.each(response.err_msg,function (i,j) {
                            $('#'+i).next().html(j[0])
                        });
                    }
                }
            })
        })
    <script/>

    四、局部钩子与全局钩子

    参见  一、校验字段功能  视图部分代码,需要注意局部钩子只有在满足第一个条件之后才会执行,如果在第一个条件不满足就不会进一步执行局部钩子代码,相反,全局钩子什么时候都会 执行。

     五、扩展

    如何往django自带的auth_user表中添加新的字段,如手机号?

    models.py

    from django.contrib.auth.models import AbstractUserclass 
    UserInfo(AbstractUser): #相当于继承了auth_user表 tel = models.CharField(max_length=32)

    settings

    AUTH_USER_MODEL = 'app01.UserInfo'    
    
    #app01自定义,为UserInfo所在的app

    随后可执行:python manage.py makemigrations

          python manage.py migrate

    这时django自带的auth_user表将会消失,取而代之的是app01_userinfo

  • 相关阅读:
    BZOJ 1096: [ZJOI2007]仓库建设
    【BZOJ1008】越狱(排列组合计数,容斥原理)
    【BZOJ1403】Divisibility Testing(数论)
    【BZOJ1225】求正整数(数论)
    高精度模板(From JCVB)
    【NOIP模拟&POJ2152】灰色的果实(树形DP)
    【BZOJ2560】串珠子(状压DP,容斥原理)
    【POJ1185】炮兵阵地(状压DP)
    【POJ3254】Corn Fields(状压DP)
    【POJ3311】Hie with the Pie(状压DP,最短路)
  • 原文地址:https://www.cnblogs.com/fengchong/p/9908917.html
Copyright © 2011-2022 走看看