BBS项目开发2

2022/9/16 6:18:41

本文主要是介绍BBS项目开发2,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

注册forms编写

专门写一个类来存form

用户名、密码、确认密码、邮箱
username = forms.CharField(max_length=8, min_length=3,required=True,error_massages={'max_length':'超出范围','min_length':'太短了','required':'这个必填'}, widget=widgets.TextInput(attrs={'class': 'form-control'}))

"""
max_length:限制最长
min_length:限制最短
required:设置这个是必须要填的
error_massages:提示错误信息
widget:渲染页面,添加一个额外属性,对某一个filed指定widget,传递一个attrs,是一个字典
"""

钩子函数校验

局部钩子校验:(clean_字段名)
    def clean_username(self):
        # 先将名字取出来
        username=self.cleaned_data.get('username')
        # 去数据库中比对该用户
        user=UserInfo.objects.filter(username=username).first()
        if user:
            # 已经存在,不合理
            raise ValidationError('该用户名已经存在')
        else:
            return username

全局钩子校验:(clean)校验多个用户
    def clean(self):
        # 比较两个密码是否一致  :cleaned_data存的是校验过后的数据,是个字典
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if password == re_password:
            # 合理,返回校验过后的数据
            return self.cleaned_data
        else:
            # 不合理,抛出校验失败的异常
            raise ValidationError('两次密码不一致!!')

注册页面搭建

在settings.py中配置静态资源的配置
STATIC_URL= '/static/'
STATICFILES_DIRS=[os.path.join(BASE_DIR, 'static')]
 -把bootstrap的静态资源copy到static文件夹下
"""
前端页面使用的是bookstrap搭建的
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
        </div>
    </div>
</div>

可以使用for循环来将我们在form里面写的所有字段写出来,那么需要我们将数据传过来,进入views.py中,实例化一个对象,然后render的第三个参数context用来传输上下文,将数据传给前端
    # 将文件导入
    from blog.blog_forms import RegisterForm

    if request.method == 'GET':
        # register_form是我们写的那个类,
        register_form = RegisterForm()
        return render(request, 'register.html', context={'form': register_form})
"""
{% for item in form %}
    <div class="form-group">
        <label for="{{ item.id_for_label }}">{{ item.label }}</label>
        {{ item }}
        <span class="pull-right text-danger"></span>
    </div>
{% endfor %}

头像要单独写出来不能写的fo循环里
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1 class="text-center">注册功能</h1>
            <form id="id_form">


                {% for item in form %}
                    <div class="form-group">
                        <label for="{{ item.id_for_label }}">{{ item.label }}</label>
                        {{ item }}
                        <span class="pull-right text-danger"></span>
                    </div>
                {% endfor %}
                <div class="form-group">
                    <label for="id_file">头像
                        <img src="/static/img/default.png" alt="" height="80px" width="80px" style="margin-left: 10px">
                    </label>
                    <input type="file" id="id_file" accept="image/*" style="display: none">
                </div>
                <div class="form-group text-center">
                    {#                    如果input类型是submit或者button标签,放在form表单中,如果点提交,触发form的提交,如果我们写了ajax提交,会触发两次提交#}
                    <input type="button" value="注册" class="btn btn-danger" id="id_submit">
                    <span class="text-danger"></span>
                </div>

            </form>
        </div>

    </div>
</div>

</body>
</html>

头像动态显示

1.给头像img标签设置一个id
2.给这个id设置一个change事件,如果图片发生了变化,那么就触发这个事件
3.借助于一个文件阅读器,它是js提供的一个类
    var reader=new FileReader()
4.拿到文件对象,赋值给一个变量
    <label for="id_file">头像<img src="/static/img/default.png" alt="" height="80px" width="80px" style="margin-left: 10px" id="id_img"></label>
    <input type="file" id="id_file" accept="image/*" style="display: none">
    var file = $("#id_file")[0].files[0]
5.把文件读到文件阅读器中
    reader.readAsDataURL(file)
6.等读完后,把文件阅读器的内容写到img标签上
    reader.onload=function (){
        $('#id_img').attr('src', reader.result)
    }

后端注册功能

def register(request):
    # get请求部分
    if request.method == 'GET':
        register_form = RegisterForm()
        return render(request, 'register.html', context={'form': register_form})
    # post请求部分
    else:
        res = {'code': 100, 'msg': '注册成功'}
        # 取出用固话名密码,使用form校验数据,如果校验通过,存到数据库中。如果校验不通过,返回错误信息
        register_form = RegisterForm(data=request.POST)  # data就是校验的数据
        if register_form.is_valid():
            # 数据字段自己的规则,局部钩子,全局钩子都校验过后,通过了然后要存到数据库中
            # 1.re_password字段不能存入数据库中,要删除掉
            # cleaned_data是校验过后的数据,赋值给变量
            register_data = register_form.cleaned_data
            # 从cleaned_data中将re_password剔除
            register_data.pop('re_password')
            # 2.头像:如果携带了要存褚在request.FILES中
            my_file = request.FILES.get('my_file')  # my_file是一个对象
            if my_file:
                # 直接把文件对象赋值给avatar后,保存成功,会把文件存放到FileField 的upload_to指定的路径下,然后该字段存放地址
                # 本质 打开了空文件,把前端传入的头像存到空文件中,然后把地址存到avatar这个地段上
                register_data['avatar'] = my_file
            # 3.存到数据库
            UserInfo.objects.create_user(**register_data)
            return JsonResponse(res)
        else:
            res['code'] = 101
            res['msg'] = '注册失败'
            res['errors'] = register_form.errors
            return JsonResponse(res)

注册功能前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <script src="/static/jquery-3.3.1/jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1 class="text-center">注册功能</h1>
            <form id="id_form" >
                {% csrf_token %}

                {% for item in form %}
                    <div class="form-group">
                        <label for="{{ item.id_for_label }}">{{ item.label }}</label>
                        {{ item }}
                        <span class="pull-right text-danger"></span>
                    </div>
                {% endfor %}
                <div class="form-group">
                    <label for="id_file">头像
                        <img src="/static/img/default.png" alt="" height="80px" width="80px" style="margin-left: 10px"
                             id="id_img">
                    </label>
                    <input type="file" id="id_file" accept="image/*" style="display: none">
                </div>
                <div class="form-group text-center">
                    {#                    如果input类型是submit或者button标签,放在form表单中,如果点提交,触发form的提交,如果我们写了ajax提交,会触发两次提交#}
                    <input type="button" value="注册" class="btn btn-danger" id="id_submit">
                    <span class="text-danger"></span>
                </div>

            </form>
        </div>

    </div>
</div>

</body>
<script>
    $("#id_file").change(function () {
        // 把当前图片,放到img标签中
        // 把图片地址放到img标签上,标签就显示了图片
        //$("#id_img")[0].src='https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg'

        // 1 id_file这个标签的图片读出来,借助于文件阅读器,js提供的一个类
        var reader = new FileReader()
        // 2 拿到文件对象,赋值给一个变量
        var file = $("#id_file")[0].files[0]
        // 3 把文件读到文件阅读器中
        reader.readAsDataURL(file)
        // 4 等读完后,把文件阅读器的内容写到img标签上
        //$("#id_img")[0].src=reader.result
        reader.onload = function () {
            //$("#id_img")[0].src=reader.result
            $('#id_img').attr('src', reader.result)
        }


    })


    // 当点击注册按钮,发送ajax请求到后端的注册功能
    $("#id_submit").click(function () {

        // 上传文件,借助于formdata对象
        var formdata = new FormData()

        // 方式一
        /*
        formdata.append('username',$('#id_username').val())
        formdata.append('password',$('#id_username').val())
        formdata.append('re_password',$('#id_username').val())
        formdata.append('my_file',$('#id_file')[0].files[0])
        // csrftoken也要加上
        */
        // 方式二:借助于form表单批量处理
        var data = $("#id_form").serializeArray()
        console.log(data)
        // 使用for循环,把data中得数据,转存到formdata中  jquery的each循环
        $.each(data, function (i, v) {
            //console.log("索引是:",i)
            //console.log("值是:",v)
            //console.log("------")
            formdata.append(v.name, v.value)
        })
        // 文件单独再放进去
        formdata.append('my_file', $('#id_file')[0].files[0])


        // 使用ajax向后端发送请求
        // 1 三种编码格式:urlencoded,form-data,json
        // {name:lqz,age:19}--->name=lqz&age=19
        $.ajax({
            url: '/register/',
            type: 'post',
            processData: false,
            contentType: false,
            data: formdata,
            success: function (data) {
                console.log(data)
                if(data.code==100){
                    // 表示注册成功,跳转到登录页面
                    location.href='/login/'
                }else {
                    // 在前端显示错误信息
                }
            }

        })

    })


</script>
</html>

头像上传路径问题

# 咱们写项目后台静态资源中得图片,一般放在static文件夹下
# 用户上传的文件,图片等,一般放在media文件夹下
	-我们想做的是,avatar文件夹要在media文件夹下

# django中只需要在配置文件中加一句话
# 以后再上传的文件路径是从media文件夹下开始
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

注册错误信息渲染

    $("#id_submit").click(function () {

        // 上传文件,借助于formdata对象
        var formdata = new FormData()

        // 方式一
        /*
        formdata.append('username',$('#id_username').val())
        formdata.append('password',$('#id_username').val())
        formdata.append('re_password',$('#id_username').val())
        formdata.append('my_file',$('#id_file')[0].files[0])
        // csrftoken也要加上
        */
        // 方式二:借助于form表单批量处理
        var data = $("#id_form").serializeArray()
        console.log(data)
        // 使用for循环,把data中得数据,转存到formdata中  jquery的each循环
        $.each(data, function (i, v) {
            //console.log("索引是:",i)
            //console.log("值是:",v)
            //console.log("------")
            formdata.append(v.name, v.value)
        })
        // 文件单独再放进去
        formdata.append('my_file', $('#id_file')[0].files[0])


        // 使用ajax向后端发送请求
        // 1 三种编码格式:urlencoded,form-data,json
        // {name:lqz,age:19}--->name=lqz&age=19
        $.ajax({
            url: '/register/',
            type: 'post',
            processData: false,
            contentType: false,
            data: formdata,
            success: function (data) {
                console.log(data)
                if(data.code==100){
                    // 表示注册成功,跳转到登录页面
                    location.href='/login/'
                }else {
                    // 在前端显示错误信息
                    console.log(data)
                    // 两次密码不一致的错误渲染
                    /*
                    if(data.errors['__all__']){
                        $(".error").html(data.errors['__all__'][0])
                    }
                    */

                    // 其他标签的错误渲染
                    $.each(data.errors,function (k,v){
                        if (k=='__all__'){ //两次密码不一致的错误渲染
                            $(".error").html(v[0])
                        }else {
                            // 链式调用,在对应的input后的span中插入错误文字,把父div加入has-error类,整个框变红
                            $("#id_"+k).next().html(v[0]).parent().addClass('has-error')
                        }

                    })

                    // 起一个定时任务
                    setTimeout(function (){
                        // 把所有span的文字去掉,把父div中得has-error类去掉
                        $('.text-danger').html("").parent().removeClass('has-error')
                    },3000)

                }
            }

        })

    })

用户校验功能呢

后端校验接口

# 前端通过get把用户名传入,我们根据用户名查询数据库,如果用户名存在,返回存在,如果不存在,返回不存在
/check_username/?username=lqz


def check_username(request):
    # /check_username/?username=lqz
    res = {'code': 100, 'msg': '用户存在'}
    username = request.GET.get('username')
    user = UserInfo.objects.filter(username=username).first()
    if user:
        # 用户存在 
        return JsonResponse(res)
    else:
        # 用户不存在
        res['code'] = 101
        res['msg'] = '用户不存在'
        return JsonResponse(res)

前端

// username输入框,失去焦点,触发ajax执行
$('#id_username').blur(function () {

    $.ajax({
        url: '/check_username/?username=' + $(this).val(),
        type: 'get',
        success: function (data) {
            if (data.code == 100) {
                // 在span中插入错误信息
                {#alert(data.msg)#}
                $('#id_username').next().html(data.msg)
            }
        }

    })
})


这篇关于BBS项目开发2的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程