BBS第二天之注册

注册渲染:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
    <script src="/static/jquery-3.3.1.js"></script>
    <title>注册</title>
    <style>
        #myfile {
            display: none;
        }
        .error{
            color:red;
        }
    </style>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1>注册</h1>
            <hr>

            <form id="myform" novalidate>
                {% csrf_token %}
                {% for field in reg_form %}
                    <div class="form-group">
                        {# field.auto_id取出当前input框自动生成的id#}
                        <label for="{{ field.auto_id }}">{{ field.label }}</label>
                        {{ field }} <span class="error pull-right"></span>
                    </div>
                {% endfor %}
                <div class="form-group">
                    <label for="myfile">头像
                        {# 把img标签放到label内                 #}
                        <img src="/static/img/default.png" height="80" width="80" id='my_img' style="margin-left: 10px">
                    </label>
                    {#当input发生变化时,来把图片显示在img中#}
                    <input type="file" id="myfile" accept="image/*">
                </div>

                <input type="button" class="btn btn-primary" value="注册" id="id_submit">

            </form>


        </div>
    </div>
</div>
</body>
<script>
    //要用change事件
    $("#myfile").change(function () {
        //取到文件对象
        var myfile = $("#myfile")[0].files[0]
        //文件阅读器,生成一个文件阅读器对象
        var filereader = new FileReader()
        //把文件读入该对象
        filereader.readAsDataURL(myfile)
        //等图片完全读入filereader中,再进行操作
        filereader.onload = function () {
            //filereader.result 文件内容,把文件内容放到src属性上
            $("#my_img").attr('src', filereader.result)
        }
    })

    $("#id_submit").click(function () {
        //ajax提交文件,得通过formdata对象
        var formdata = new FormData()
        /*复杂方式
        formdata.append('username',$("#id_username").val())
        formdata.append('password',$("#id_password").val())
        formdata.append('re_password',$("#re_password").val())
        */
        //取到form表单
        console.log($("#myform").serializeArray())
        var upload_data = $("#myform").serializeArray()
        //jq的循环:两个参数,第一个参数是要循环的对象,第二个参数传一个匿名函数
        $.each(upload_data, function (index, obj) {
            //console.log(index)
            //console.log(obj)---{'name':'username','value':'lqz'}
            //这里添加的内容包括csrf的东西
            formdata.append(obj.name, obj.value)
        })

        //把csrf添加到formdata中
        //取到csrf值得两种方式,
        //第一种:'{{ csrf_token }}'
        //第二种方式:jq取值:$("[name='csrfmiddlewaretoken']").val()
        //formdata.append('csrfmiddlewaretoken','{{ csrf_token }}')
        //formdata.append('csrfmiddlewaretoken',$("[name='csrfmiddlewaretoken']").val())
        //手动把文件放到formdata中
        formdata.append('myfile', $("#myfile")[0].files[0])
        //提交ajax请求
        $.ajax({
            url: '/register/',
            type: 'post',
            //上传文件
            processData: false,
            contentType: false,
            data: formdata,
            success: function (data) {
                //console.log(data)
                if(data.status==100){
                    //注册成功,跳转
                    location.href=data.url
                    //location.href='/login/'
                }else {
                    //console.log(data.msg)
                    //清空错误信息
                    $("span.error").text("")
                    $(".form-group").removeClass('has-error')
                    //循环错误信息
                    $.each(data.msg,function (field,obj) {
                        console.log(field)
                        console.log(obj)
                        //谁的错误,显示在谁的span中
                        //$("#id_"+field)取到有错误信息的input框,next取到下一个标签也就是span,在span标签中把错误信息写入
                       // $("#id_"+field).next().html(obj[0])
                        //$("#id_"+field).next().parent().addClass('has-error')
                        //支持链式操作
                        var aa='#id_'+field
                        alert(aa)
                        $(aa).next().html(obj[0]).parent().addClass('has-error')
                        if(field=='__all__'){
                            //当两次密码不一致的时候,在确认密码的span标签中渲染错误信息
                            $("#id_re_password").next().html(obj[0])
                        }
                        //过3秒清掉错误信息
                        setTimeout(function () {
                            $("span.error").text("")
                            $(".form-group").removeClass('has-error')
                            //清掉value的值
                        },3000)
                    })
                }

            }
        })

    })
</script>
</html>

form字段的创建及校验:

from django import forms
from django.forms import widgets
from app01 import models
from django.core.exceptions import ValidationError


class RegForm(forms.Form):
    username = forms.CharField(max_length=8, min_length=3, label='用户名',
                               error_messages={'max_length': '用户名过长', 'min_length': '太短了', 'required': '该项必填'},
                               widget=widgets.TextInput(attrs={'class': 'form-control'}))
    password = forms.CharField(max_length=8, min_length=3, label='密码',
                               error_messages={'max_length': '密码名过长', 'min_length': '太短了', 'required': '该项必填'},
                               widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    re_password = forms.CharField(max_length=8, min_length=3, label='确认密码',
                                  error_messages={'max_length': '确认密码过长', 'min_length': '太短了', 'required': '该项必填'},
                                  widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
    email = forms.EmailField(error_messages={'required': '该项必填', 'invalid': '格式错误'},
                             widget=widgets.EmailInput(attrs={'class': 'form-control'}))

    # 局部校验username字段
    def clean_username(self):
        name = self.cleaned_data.get('username')
        user = models.UserInfo.objects.filter(username=name).first()
        if user:
            raise ValidationError('该用户已存在')
        else:
            return name

    # 全局校验两次密码是否一致
    def clean(self):
        pwd = self.cleaned_data.get('password')
        re_pwd = self.cleaned_data.get('re_password')
        if not pwd == re_pwd:
            raise ValidationError('两次密码不一致')
        else:
            return self.cleaned_data

注册视图函数:

from app01.myforms import RegForm
from app01 import models


# Create your views here.
def register(request):
    response_dic = {'status': 100, 'msg': None}
    reg_form = RegForm()
    if request.method == 'POST':
        # 生成一个RegForm对象,用于校验前台传过来的数据
        reg_form = RegForm(request.POST)
        # 当reg_form.is_valid()是True,表示数据校验通过
        if reg_form.is_valid():
            # 取到清洗完的数据,内部带着re_re_password
            clean_data = reg_form.cleaned_data
            # 需要把re_password移除
            clean_data.pop('re_password')
            # 要用create_user来创建用户
            # {'username':'lqz','password':'123'}
            # 比较复杂一些
            # name = clean_data.get('username')
            # pwd = clean_data.get('password')
            # eamil = clean_data.get('email')
            # # 取到文件对象
            # myfile = request.FILES.get('myfile')
            # # 坑,myfile必须有值
            # # 直接把文件对象赋值给avatar,它会自动保存到upload_to='avatar/'
            # if myfile:
            #     models.UserInfo.objects.create_user(username=name, password=pwd, email=eamil, avatar=myfile)
            # else:
            #     models.UserInfo.objects.create_user(username=name, password=pwd, email=eamil)
            # 简单一些
            myfile = request.FILES.get('myfile')
            if myfile:
                clean_data['avatar'] = myfile
            models.UserInfo.objects.create_user(**clean_data)
            response_dic['msg'] = '注册成功'
            response_dic['url'] = '/login/'

        else:
            # 注册失败,返回错误信息,和状态码
            response_dic['status'] = 101
            response_dic['msg'] = reg_form.errors
        return JsonResponse(response_dic)

    return render(request, 'register.html', {'reg_form': reg_form})

效果图:

 

posted @ 2019-08-21 18:18  纵横捭阖行  阅读(151)  评论(0编辑  收藏  举报