zoukankan      html  css  js  c++  java
  • DAY88-BBS项目(二) 注册

    BBS之注册功能

    前端

    模板层

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
        {% load static %}
        <link rel="stylesheet" href="{% get_static_prefix %}bootstrap-3.3.7-dist/css/bootstrap.css">
        <script src="{% get_static_prefix %}jquery-3.3.1.js"></script>
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-4 col-md-offset-4 bg-success clearfix img-rounded" style="padding-bottom: 30px">
                <h1 style="text-align: center">注册</h1>
                <form id="reg_form" novalidate>
                    {% csrf_token %}
                    {% for foo in my_form %}
                        <div class="form-group">
                            <label for="{{ foo.auto_id }}">{{ foo.label }}</label><span style="color: red;" id="error"
                                                                                        class="pull-right"></span>
                            {{ foo }}
                        </div>
                    {% endfor %}
                    <div class="form-group">
                        <label for="my_file">头像&nbsp;&nbsp;&nbsp;&nbsp;
                            <img src="/static/image/default.png" alt="" id="picture" width="80" height="80">
                        </label>
                        <input type="file" class="hidden" id="my_file" required>
                    </div>
                </form>
                <span style="margin-left: 230px;color: red" id="msg"></span>
                <button type="button" class="btn btn-info btn-lg pull-right active " id="btn">注册</button>
            </div>
    
        </div>
    </div>
    </body>
    <script>
        $('#my_file').change(function () {
            // 先获得图片$('#my_file')[0].files[0],生成图片对象file
            var file = $(this)[0].files[0];
            // 生成一个文件阅读器
            var read = new FileReader();
            // 文件阅读器读入图片
            read.readAsDataURL(file);
            // 由于图片是属于页面资源,必须等页面加载完才显示图片
            read.onload = function () {
                $('#picture').attr('src', read.result)
            }
        })
    
        $('#btn').click(function () {
            var formdata = new FormData();
            // 调用表单的serializeArray()方法序列化表单元素,以列表套字典[{name: "username", value: ""},.....]
            var arrt = $('#reg_form').serializeArray();
            // $.each(被循环的,循环体(匿名函数)):JQ的循环方法
            $.each(arrt, function (index, data) {
                formdata.append(data.name, data.value)
            })
    
            // 单独添加文件
            formdata.append('my_file', $('#my_file')[0].files[0]);
    
            $.ajax({
                url: '/register/',
                type: 'post',
                processData: false,
                contentType: false,
                data: formdata,
                success: function (data) {
                    if (data.status == '200') {
                        $('#msg').text('注册成功')
                    }
                    else if (data.status == '404') {
                        $('#msg').text('头像上传失败')
                    }
                    else if (data.status == '401') {
                         // data.error得到的是错误信息,字典套列表{'username':[错误信息]..},循环得到key值
                        for (let i in data.error) {
                            // 循环判断错误的是那些
                            $.each(arrt, function (index, value) {
                                if (i == value.name) {
                                    // 把input的前一个同辈标签span的text变成错误信息data.error[i][0]
                                    $('#id_' + i).prev('span').text(data.error[i][0])
                                }
                            })
                        }
                        // 如果有全局错误信息,显示到$('#msg').text(data.error['__all__'])
                        if (data.error['__all__']) {
                            $('#msg').text(data.error['__all__'])
                        }
                    }
                }
            })
    
        })
    
    </script>
    </html>
    

    后端

    forms组件

    from django import forms
    from django.forms import widgets
    from blog.models import UserInfo
    from django.core.exceptions import ValidationError
    
    
    class User_from(forms.Form):
        username = forms.CharField(label='用户名', max_length=10, min_length=3,widget=widgets.TextInput(attrs={'class': 'form-control'}),error_messages={'max_length': '最长是19', 'min_length': '最短是3', 'required': '不能为空'}, )
        
        password = forms.CharField(label='密码', max_length=10, min_length=3,widget=widgets.PasswordInput(attrs={'class': 'form-control'}),error_messages={'max_length': '最长是0', 'min_length': '最短是3', 'required': '不能为空'})
        
        re_password = forms.CharField(label='确认密码', max_length=10, min_length=3,widget=widgets.PasswordInput(attrs={'class': 'form-control'}),error_messages={'max_length': '最长是10', 'min_length': '最短是3', 'required': '不能为空'})
        
        email = forms.EmailField(label='邮箱', error_messages={'required': '不能为空','invalid': '不符合邮箱格式'},widget=widgets.EmailInput(attrs={'class': 'form-control'}))
    
        def clean_username(self):
            name = self.cleaned_data.get('username')
            name_db = UserInfo.objects.filter(username=name).first()
            if name_db:
                raise ValidationError('用户已存在')
            return name
    
        def clean(self):
            pwd = self.cleaned_data.get('password')
            re_pwd = self.cleaned_data.get('re_password')
            if pwd and re_pwd:
                if pwd != re_pwd:
                    raise ValidationError('两次密码不一致')
            return self.cleaned_data
    

    视图层

    from django.shortcuts import render, HttpResponse
    from django.http import JsonResponse
    from blog import myform
    from blog.models import UserInfo
    def register(requset):
        response = {'status': 200, 'error': None}
        if requset.method == 'POST':
            # 将所有POST数据放入放入form组件验证
            my_form = myform.User_from(requset.POST)
            # 验证通过
            if my_form.is_valid():
                # 将验证通过的数据放到dic里
                dic = my_form.cleaned_data
                # 去除不需要存入数据库的re_password
                dic.pop('re_password')
                # 获得文件
                my_file = requset.FILES.get('my_file')
                # 为了区分头像,加上前缀
                my_file.name = requset.POST.get('username') + '_' + my_file.name
                if my_file:
                    # 在dic中添加头像数据
                    dic['avatar'] = my_file
                    # 创建用户
                    UserInfo.objects.create_user(**dic)
                else:
                    response['status'] = 404
            else:
                response['status'] = 401
                response['error'] = my_form.errors
            return JsonResponse(response)
        my_form = myform.User_from()
        return render(requset, 'register.html', locals())
    

    总结

    基于forms组件和Ajax实现注册功能
    
    
    # 1 基于forms组件设计注册页面
    
    
       ---点击头像===点击input
    
       ---头像预览:
          1 获取用户选中的文件对象
          2 获取文件对象的路径
          3 修改img的src属性 ,src=文件对象的路径
    
    # 2 错误信息:
       
        // data.error得到的是错误信息,字典套列表{'username':[错误信息]..},循环得到key值
    for (let i in data.error) {
        // 循环判断错误的是那些
        $.each(arrt, function (index, value) {
            if (i == value.name) {
                // 把input的前一个同辈标签span的text变成错误信息data.error[i][0]
                $('#id_' + i).prev('span').text(data.error[i][0])
            }
        })
    }
    // 如果有全局错误信息,显示$('#msg').text(data.error['__all__'])
    if (data.error['__all__']) {
        $('#msg').text(data.error['__all__'])
    }
    
    # 3 局部钩子和全局钩子校验
       user字段不能重复
       两次密码不一致
    
    
    
    # 4 FileField与ImageFiled
    区别是:
    fileField是可以任何文件
    ImageFile只能是图片文件
    class UserInfo(AbstractUser):
        nid = models.AutoField(primary_key=True)
        # 电话可以为空
        phone = models.CharField(max_length=32, null=True)
        # 头像
        avatar = models.FileField(upload_to='static/avatar/', default='/static/image/default.png')
        # 站点
        blog = models.OneToOneField(to='Blog', to_field='nid',null=True)
    
      Dajngo实现:
    
          会将文件对象下载到项目中avatars文件夹中(如果没有avatar文件夹,Django会自动创建)
    
  • 相关阅读:
    js 正则表达式
    JAVA jdk环境搭建
    VMWareStation10 密钥
    linux xshell jdk hadoop(环境搭建) 虚拟机 安装(大数据搭建环境)
    linux hadoop jdk虚拟机下配置
    Linux shell基础(四)
    Linux shell基础(二)
    Linux shell基础(三)
    Linux shell基础(一)
    html
  • 原文地址:https://www.cnblogs.com/xvchengqi/p/10034163.html
Copyright © 2011-2022 走看看