网站之注册

本次注册时的需求:

1.用ajax提交数据

2.用form表单渲染数据

3.上传头像是二进制数据用formData

4.上传头像需要专门地方存放:需要配置Media。

5.上传头像需要预览.

首先配置media:

a.setting里面的配置

MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media","uploads")
MEDIA_URL="/media/"

b.全局的urls里面的配置(因为系统没有配置的server)

  # media 配置
    url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT})

首先先写form表单:(钩子函数写在后面)

from django import forms

from django.forms import widgets,ValidationError


from blog import models

class RegForm(forms.Form):#定义

    username=forms.CharField(
        max_length=12,
        min_length=5,
        required=True,
        error_messages={
        "required":"不能为空",
    },
        widget=widgets.TextInput(attrs={"class":"form-control","placeholder":"username"}))

    password=forms.CharField(
        min_length=6,
        widget=widgets.PasswordInput(
        attrs={"class": "form-control", "placeholder": "password"}
    ))

    repeat_pwd=forms.CharField(
        min_length=6,widget=widgets.PasswordInput(
        attrs={"class": "form-control", "placeholder": "repeat_pwd"}
    ))

    email=forms.EmailField(widget=widgets.EmailInput(
        attrs={"class": "form-control", "placeholder": "email"}
    ))


    def clean_username(self):#定义局部钩子函数form表单里的数据都在cleaned_data

        ret=models.UserInfo.objects.filter(username=self.cleaned_data.get("username"))
        if not ret:
            return self.cleaned_data.get("username")#返回的都是自己的数据
        else:
            raise ValidationError("用户名已注册")

    def clean_password(self):
        data=self.cleaned_data.get("password")

        if not data.isdigit():
            return self.cleaned_data.get("password")
        else:
            raise ValidationError("密码不能全是数字")


    def clean_validCode(self):#定义验证验证码的钩子因为没有request需要自己的定义一个
        if self.cleaned_data.get("validCode")== self.request.session.get("validCode"):
            return self.cleaned_data.get("validCode")

        else:
            raise  ValidationError("验证码错误")
    def clean(self):
        if self.cleaned_data.get("password") == self.cleaned_data.get("repeat_pwd"):
            return self.cleaned_data

        else:
            raise  ValidationError("两次密码不一致")

    def __init__(self,request,*args,**kwargs):#这是为验证验证码自定义的一个
        super().__init__(*args,**kwargs)#继承父辈
        self.request=request
Form表单的数据

Views视图里的注册函数:

def reg(request):

    if request.is_ajax():
        form_obj=forms.RegForm(request,request.POST)

        regResponse={"user":None,"errorsList":None}#这个是给ajax返回数据用的
        if form_obj.is_valid():#判断是否通过钩子函数

            username=form_obj.cleaned_data["username"]
            password=form_obj.cleaned_data["password"]
            email=form_obj.cleaned_data.get("email")
            avatar_img=request.FILES.get("avatar_img")
            if  avatar_img:#如果拿到上传的头像就用上传的

                user_obj=models.UserInfo.objects.create_user(username=username,password=password,email=email,avatar=avatar_img,nickname=username)
            else:#否则就用默认的
                user_obj=models.UserInfo.objects.create_user(username=username,password=password,email=email,nickname=username)

            print(user_obj.avatar,"......")
            regResponse["user"]=user_obj.username
        else:
            regResponse["errorsList"]=form_obj.errors#所有错误的数据都放在errors里面
        import json
        return HttpResponse(json.dumps(regResponse))





    form_obj=forms.RegForm(request)#在没有数据时渲染页面,定义form时用(form.From)这里就要用request
    return render(request,"reg.html",{"form_obj":form_obj})
View Code

reg.tml页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>

    <script src="/static/dist/js/jquery-3.1.1.js"></script>
    <script src="/static/dist/js/bootstrap.js"></script>

    <link rel="stylesheet" href="/static/dist/css/bootstrap.css">

    <link rel="stylesheet" href="/static/css/reg.css">
    <script src="/static/js/jquery.cookie.js"></script>
</head>
<body>



<div class="container">
    <div class="row">
        <div class="col-md-5 col-md-offset-3">
            <form>
                      {% csrf_token %}<!--用form表单一定要用这个-->
                      <div class="form-group">
                        <label for="username">用户名</label>
                        {{ form_obj.username }}
                      </div>
                      <div class="form-group">
                        <label for="password">密码</label>
                        {{ form_obj.password }}
                      </div>

                       <div class="form-group">
                        <label for="password">确认密码</label>
                           {{ form_obj.repeat_pwd }}
                      </div>

                      <div class="form-group">
                        <label for="email">邮箱</label>
                          {{ form_obj.email }}
                      </div>

                      <div class="form-group avatar">
                        <label for="avatar">头像</label>
                        <img src="/static/img/default.png" alt="" id="avatar_img"><!--这里是和inpu放在一起通过css控制-->
                        <input type="file" class="form-control" id="avatar_file" ><!--这是上传头像的-->
                      </div>


                    <input type="button" value="submit" class="btn btn-primary" id="subBtn"><span class="error"></span>

                </form>
        </div>
    </div>
</div>

<script>
    // 头像预览

    $("#avatar_file").change(function () {

        var ele_file=$(this)[0].files[0];  //this.files
        var reader=new FileReader();
        reader.readAsDataURL(ele_file);
        reader.onload=function () {
            $("#avatar_img")[0].src=this.result
        }

    });

    $("#subBtn").click(function () {
        <!--用formData上传二进制数据-->
        var formdata=new FormData();
        formdata.append("username",$("#id_username").val());
        formdata.append("password",$("#id_password").val());
        formdata.append("repeat_pwd",$("#id_repeat_pwd").val());
        formdata.append("email",$("#id_email").val());
        formdata.append("avatar_img",$("#avatar_file")[0].files[0]);
        $(".pull-right").html("");
        $(".pull-right").parent().removeClass("has-error");

        $.ajax({
            url:"/reg/",
            type:'POST',
            data:formdata,
            contentType:false,
            processData:false,
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            success:function (data) {
{#                  console.log(data);#}
                var data=JSON.parse(data);

                if (data.user){
                    location.href="/login/"
                }
                else {

                    console.log(data.errorsList);

                   $.each(data.errorsList,function (i,j) {
                       console.log(i,j);

                       $span=$("<span>");
                       $span.addClass("pull-right").css("color","red");
                       $span.html(j[0]);
                       $("#id_"+i).after($span).parent().addClass("has-error")
                       console.log($("#id_"+i).next($span))

                       if (i=="__all__"){<!--这是用来判断全局钩子的-->
                            $("#id_repeat_pwd").after($span)
                       }
                   })


                }


            }
        })
    })
</script>



</body>
</html>
View Code


原文地址:https://www.cnblogs.com/1a2a/p/7894668.html