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会自动创建)

猜你喜欢

转载自www.cnblogs.com/xvchengqi/p/10034163.html