Jump to content
  • Hello visitors, welcome to the Hacker World Forum!

    Red Team 1949  (formerly CHT Attack and Defense Team) In this rapidly changing Internet era, we maintain our original intention and create the best community to jointly exchange network technologies. You can obtain hacker attack and defense skills and knowledge in the forum, or you can join our Telegram communication group to discuss and communicate in real time. All kinds of advertisements are prohibited in the forum. Please register as a registered user to check our usage and privacy policy. Thank you for your cooperation.

    TheHackerWorld Official

学习python-Day61

 Share


KaiWn

Recommended Posts

  • 创建一个文件关于forms的校验代码。

    from django import forms
    from django.forms import widgets
    from django.core.exceptions import ValidationError
    from blog.models import UserInfo  # d导入模块:相对导入和绝对导入
    
    
    class RegisterForm(forms.Form):
        # 用户名 密码 确认密码 邮箱
        username = forms.CharField(max_length=8, min_length=3, required=True, label='用户名',
                                   error_messages={
                                       'max_length': '用户名过长',
                                       'min_length': '用户名过短',
                                       'required': '这个必填哦!',
                                   }, widget=widgets.TextInput(attrs={'class': 'form-control'}))
        password = forms.CharField(max_length=8, min_length=3, required=True, 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, required=True, label='确认密码',
                                      error_messages={
                                          'max_length': '用户名过长',
                                          'min_length': '用户名过短',
                                          'required': '这个必填哦!',
                                      }, widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
        email = forms.EmailField(label='邮箱', widget=widgets.EmailInput(attrs={'class': 'form-control'}))
    
        # 局部钩子校验
    
        def clean_username(self):
            username = self.cleaned_data.get('username')
    
            # 方案一:
            user = UserInfo.objects.filter(username=username).first()
            if user:
                #用户已存在,不合理
                raise ValidationError('用户已存在')
            else:
                #将校验后的用户返回出去
                return username
    
            # 方案二:
            # try:
            #     UserInfo.objects.get(username=username)  # 有且只有一条才行,否则就抛出异常。
            #     raise ValidationError('用户已存在!')
            # except Exception as e:
            #     return username
            #这是一个与问题的代码。
    
        # 全局钩子校验
        def clean(self):
            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('两次密码不一致!')

    二、注册页面搭建

    # bootstrap 搭建
    	settings.py  中加入 static
        	STATIC_URL = '/static/'
            STATICFILES_DIRS=[
                os.path.join(BASE_DIR, 'static')
            ]
        bootstrap的静态资源copystatic文件夹下。
    #新建模板文件  register.html
    <body>
    <div>
        <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">
                    {# 没写这串代码会出现403权限错误#}
                    {% 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 calss="form-group">
                            <label for="id_file">头像
                                <img src="/static/img/default.png" alt="" id="id_img" 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类型typesubmit或者button标签,或者form表单中,如果点提交,触发form的提交,如果写了ajax提交,会触发两次提交#}
                            <input type="button" value="注册" class="btn btn-success" id="id_submit">
                            <span class="text-danger error"></span>
                        </div>
    
                    </form>
                </div>
            </div>
    
        </div>
    
    </div>
    </body>

    image

    三、头像动态显示

    1.首先读文件,然后将读取到文件的阅读器将其放置在标签上面。
     $("#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)
            }
    
        })

    image

    四、注册功能后端

    2.views.py
    def register(request):
        if request.method == 'GET':
            register_form = RegisterForm()
            # context: 上下文
            return render(request, 'register.html', context={'form': register_form})
        else:  # post请求的时候
            res = {'code': 100, 'msg': '注册成功'}
            # 取出用户名密码,使用form校验数据,如果校验通过,存到数据库中,如果校验不通过,返回错误信息
            register_form = RegisterForm(data=request.POST)
            if register_form.is_valid():
                # 数据字段自己的规则,局部钩子,全局钩子都校验过后,通过了
                # 1  re_password字段,不存到数据库的,剔除
                register_data = register_form.cleaned_data
                register_data.pop('re_password')
                # 2 头像:如果携带了要存,头像是文件,在request.FILES中
                my_file = request.FILES.get('my_file')
                if my_file:
                    register_data['avatar'] = my_file
                # 2 存到数据库
                UserInfo.objects.create_user(**register_data)
                # UserInfo.objects.create_user(username=register_data.get('username'),) 等同于上面,但是麻烦
                return JsonResponse(res)
            else:
                res['code'] = 101
                res['msg'] = '注册失败'
                res['errors'] = register_form.errors
                return JsonResponse(res)

    五、头像上传路径问题

    注意:
    项目后台静资源中得到图片,一般放在static文件夹下,
    用户上传的文件,图片一般放在media文件夹下。文件路径先是在avatar文件夹下再是media文件夹下面,
    django中需要在配置文件中加一句话
    MEDIA_ROOT = os.path.jojin(BASE_DIR, 'media')

    六、注册错误信息渲染

    //当点击注册按钮,发送ajax请求到后端的注册功能
        $("#id_submit").click(function () {
            //上传文件,借助formdata对象
            var formdata = new FormData()
    
            //方式一
            {#formdata.append('username',$('#id_username').val())#}
            {#formdata.append('password',$('#id_password'.val()))#}
            {#formdata.append('re_password',$('#id_re_password'.val()))#}
            {#formdata.append('email',$('#id_email').val())#}
            {#formdata.append('my_file',$('#id_file')[0].files[0])#}
    
    
            //方式二:借助form表单批量处理
            var data = $("#id_form").serializeArray()
            {#console.log(data)#}
            //使用for循环,把data中的数据,转存到formdata   jqueryeach循环
            $.each(data, function (i, v) {
                //i为索引值, v是每个数据值
                formdata.append(v.name, v.value)
            })
            //文件单独再放进去,不能循环文件放进去,不然会出错的。
            formdata.append('my_file', $('#id_file')[0].files[0])
    
            //使用ajax向后端发送请求
            //1.  三种编码格式:urlencoded, form-data,json
            //urlencoded 的默认格式:{name:xz, age19}---》name=xz&age=19
            $.ajax({
                url: '/register/',
                type: 'post',
                processData: false,
                contentType: false,
                data: formdata,
                //view视图函数里面的JsonResponse的返回值
                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){
                            console.log(k)
                            console.log(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)
                    }
            })

    image

    七、用户存在校验功能

    # 前端通过get把用户传入,我们可以根据用户名查询数据库,如果用户名存在,返回存在。如果不存在,返回不存在
    /check_username/?username=xzx
    
    def check_username(request):
        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)

    八、前端校验功能

      $("#id_username").blur(function(){
                $.ajax({
                    url:'/check_username/?username=' +$(this).val(),
                    type: 'get',
                    success:function (data){
                        if(data.code == 100){
                            //在span中插入错误信息
                            {# alter(data.msg) #}
                            $("#id_username").next().html(data.msg)
                        }
                    }
                })
            })
Link to post
Link to comment
Share on other sites

 Share

discussion group

discussion group

    You don't have permission to chat.
    • Recently Browsing   0 members

      • No registered users viewing this page.
    ×
    ×
    • Create New...