04 用戶註冊

編輯本目錄html

基於forms組件建立表單

建立forms前端

from django import forms
from django.forms import widgets
class UserInfo(forms.Form):
    user=forms.CharField(max_length=32,label="用戶名",widget=widgets.TextInput(attrs={"class":'form-control'}))
    pwd=forms.CharField(max_length=32,label="密碼",widget=widgets.PasswordInput(attrs={"class":"form-control"}))
    re_pwd=forms.CharField(max_length=32,label="確認密碼",widget=widgets.PasswordInput(attrs={"class":"form-control"}))
    email=forms.EmailField(max_length=32,label="郵箱地址",widget=widgets.EmailInput(attrs={"class":'form-control'}))
View Code

html中渲染forms組件jquery

<form>
    {% csrf_token %}
    {% for field in form %}
        <div class="form-group">
            <label for="{{ field.id_for_label }}">{{ field.label }}:</label>{{ field }}
        </div>
    {% endfor %}
    <input type="button" class="button form-control btn-success" value="提交">
</form>
View Code

添加用戶頭像

添加用戶圖像圖標

添加一個img標籤,鏈接到static下的一個default.png文件ajax

技巧:django

  • 利用label的for屬性,讓點擊圖片等同於點擊input標籤
  • 將input[type='file']的標籤隱藏掉,設置display屬性爲none
<div class="container">
    <div class="row">
        <div class="col-md-4 col-lg-offset-4">
            <form>
                {% csrf_token %}
                {% for field in form %}
                    <div class="form-group">
                        <label for="{{ field.id_for_label }}">{{ field.label }}:</label>{{ field }}
                    </div>
                {% endfor %}
                <div class="form-group">
                    <label for="avatar">頭像
                        <img class="avatar_img" src="/static/app/img/default.png" style="width: 60px;height: 60px;display: inline">
                    </label>
                    <input type="file" id="avatar" style="display: none;">
                </div>
                <input type="button" class="button form-control btn-success" value="提交">
            </form>
        </div>
    </div>
</div>
View Code

用戶頭像預覽功能

  • 獲取用戶選中的文件對象,經過input標籤的change事件來觸發
  • 獲取文件對象的本地路徑,必定要等圖片加載完成以後再來獲取文件路徑
  • 修改img的src屬性值
<script>
    $('#avatar').change(function () {
        //獲取用戶選中的文件對象
       var file_obj=$(this)[0].files[0];
        //獲取當前文件對象路徑
        var reader=new FileReader();//實例化一個reader
        reader.readAsDataURL(file_obj);//讀取文件對象路徑,讀取完成後放在reader本身內部
        //待讀取完後,獲取url和修改imgsrc屬性
        reader.onload=function () {
            var file_url=reader.result;//獲取文件路徑url
            //修改img標籤的src屬性
            $('#avatar_img').attr('src',file_url);
        };
    })
</script>
View Code

 

用ajax提交formdata數據

ajax數據提交

  • 上傳的data爲formdata,須要new一個
  • contentType爲false
  • processData爲false

方式一建立formdata的ajax代碼app

<script>
    //提交formdata數據
    $('input[type="button"]').click(function () {
        var formdata=new FormData();
        formdata.append("user",$("#id_user").val());
        formdata.append("pwd",$("#id_pwd").val());
        formdata.append("re_pwd",$("#id_re_user").val());
        formdata.append("email",$("#id_email").val());
        formdata.append("avatar",$("#avatar")[0].files[0]);
        formdata.append("csrfmiddlewaretoken",$("input[name='csrfmiddlewaretoken']").val());
        $.ajax({
            url:'',
            data:formdata,
            type:'post',
            contentType:false,
            processData:false,
            success:function (data) {
                console.log(data)
            },
            error:function (err) {
                console.log(err)
            }
        })
    })
</script>
View Code

方式二建立formdataide

<script>
    //提交formdata數據
    $('input[type="button"]').click(function () {
        var formdata=new FormData();formdata.append("csrfmiddlewaretoken",$("input[name='csrfmiddlewaretoken']").val());#}
        var formarray= $("#form").serializeArray();
        $.each(formarray,function (index, data) {
            formdata.append(data.name,data.value);
        });
        formdata.append("avatar",$("#avatar")[0].files[0]);

        $.ajax({
            url:'',
            data:formdata,
            type:'post',
            contentType:false,
            processData:false,
            success:function (data) {
                console.log(data)
            },
            error:function (err) {
                console.log(err)
            }
        })
    })
</script>
View Code

 views代碼,可經過is_ajax()驗證,也能夠經過request.POST驗證post

def register(request):
    # if request.method=='POST':
    if request.is_ajax():
        response={"user":None,"msg":None}
        form=UserInfoForm(request.POST)
        if form.is_valid():
            response['user']=form.cleaned_data.get('user');
        else:
            print(form.cleaned_data)
            print(form.errors)
            response['msg']=form.errors
        return JsonResponse(response)
View Code

 加載error提示

  • 經過jquery的each方法循環errs,每一個error的index對應的和input的id有規律,其實也能夠用name直接獲取。查找到input標籤後,經過next方法查找下一個標籤
  • 在將error寫入span以前,須要將全部的error信息清除掉,不然第二次提交的是第一次的error信息任然

JavaScript代碼ui

<script>
    //提交formdata數據
    $('input[type="button"]').click(function () {
        var formdata=new FormData();
        var formarray= $("#form").serializeArray();
        $.each(formarray,function (index, data) {
            formdata.append(data.name,data.value);
        });
        formdata.append("avatar",$("#avatar")[0].files[0]);
        $.ajax({
            url:'',
            data:formdata,
            type:'post',
            contentType:false,
            processData:false,
            success:function (data) {
                if(data.msg){
                    //數據校驗失敗,致使註冊失敗
                    //動態加載錯誤信息
                    $(".error").html("");//先清空一次,避免上次錯誤信息任然存在
                    $(".form-group").removeClass('has-error');
                    $.each(data.msg,function (index,error_list) {
                        $("#id_"+index).next().html(error_list[0]);
                        $("#id_"+index).parent().addClass('has-error');//錯誤字段邊框變紅
                    })
                }else{
                    //註冊成功
                }
            },
            error:function (err) {
                console.log(err)
            }
        })
    })
</script>
View Code

錯誤信息修改爲中文提示

在form字段中,添加error_message參數this

class UserInfo(forms.Form):
    user=forms.CharField(max_length=32,label="用戶名",
                         widget=widgets.TextInput(attrs={"class":'form-control'}),
                         error_messages={"required":"用戶名不能爲空"})
    pwd=forms.CharField(max_length=32,label="密碼",
                        widget=widgets.PasswordInput(attrs={"class":"form-control"}),
                         error_messages={"required":"密碼不能爲空"})
    re_pwd=forms.CharField(max_length=32,label="確認密碼",
                           widget=widgets.PasswordInput(attrs={"class":"form-control"}),
                         error_messages={"required":"確認密碼不能爲空"})
    email=forms.EmailField(max_length=32,label="郵箱地址",
                           widget=widgets.EmailInput(attrs={"class":'form-control'}),
                         error_messages={"required":"郵箱不能爲空"})
View Code

鉤子校驗數據

局部鉤子檢查用戶名是否已經註冊

class RegisterUser(forms.Form):
    user=forms.CharField(max_length=32,label="用戶名",
                         widget=widgets.TextInput(attrs={"class":'form-control'}),
                         error_messages={"required":"用戶名不能爲空"})
    pwd=forms.CharField(max_length=32,label="密碼",
                        widget=widgets.PasswordInput(attrs={"class":"form-control"}),
                         error_messages={"required":"密碼不能爲空"})
    re_pwd=forms.CharField(max_length=32,label="確認密碼",
                           widget=widgets.PasswordInput(attrs={"class":"form-control"}),
                         error_messages={"required":"確認密碼不能爲空"})
    email=forms.EmailField(max_length=32,label="郵箱地址",
                           widget=widgets.EmailInput(attrs={"class":'form-control'}),
                         error_messages={"required":"郵箱不能爲空"})
    #局部鉤子校驗用戶
    def clean_user(self):
        val=self.cleaned_data.get('user')
        user=UserInfo.objects.filter(username=val).first()
        if not user:
            #返回原來的val
            return val
        else:
            raise ValidationError("該用戶已註冊")
View Code

全局鉤子檢查兩次密碼是否一致

class RegisterUser(forms.Form):
    user=forms.CharField(max_length=32,label="用戶名",
                         widget=widgets.TextInput(attrs={"class":'form-control'}),
                         error_messages={"required":"用戶名不能爲空"})
    pwd=forms.CharField(max_length=32,label="密碼",
                        widget=widgets.PasswordInput(attrs={"class":"form-control"}),
                         error_messages={"required":"密碼不能爲空"})
    re_pwd=forms.CharField(max_length=32,label="確認密碼",
                           widget=widgets.PasswordInput(attrs={"class":"form-control"}),
                         error_messages={"required":"確認密碼不能爲空"})
    email=forms.EmailField(max_length=32,label="郵箱地址",
                           widget=widgets.EmailInput(attrs={"class":'form-control'}),
                         error_messages={"required":"郵箱不能爲空"})
    #全局鉤子驗證兩次密碼
    def clean(self):
        pwd=self.cleaned_data.get('pwd')
        re_pwd=self.cleaned_data.get('re_pwd')
        if pwd and re_pwd:
            if pwd == re_pwd:
                return self.cleaned_data
            else:
                raise ValidationError('兩次密碼不一致')
        else:
            return self.cleaned_data
View Code

注意:全局鉤子的錯誤放在__all__中的,因此each循環的時候判斷是不是__all__便可判斷是否爲全局錯誤信息

前端JavaScript展現全局錯誤信息

<script>
    //提交formdata數據
    $('input[type="button"]').click(function () {
        var formdata=new FormData();
        var formarray= $("#form").serializeArray();
        $.each(formarray,function (index, data) {
            formdata.append(data.name,data.value);
        });
        formdata.append("avatar",$("#avatar")[0].files[0]);

        $.ajax({
            url:'',
            data:formdata,
            type:'post',
            contentType:false,
            processData:false,
            success:function (data) {
                if(data.msg){
                    //數據校驗失敗,致使註冊失敗
                    //動態加載錯誤信息
                    $(".error").html("");//先清空一次,避免上次錯誤信息任然存在
                    $(".form-group").removeClass('has-error');
                    $.each(data.msg,function (index,error_list) {
                        if(index == '__all__'){//
                            $("#id_re_pwd").next().text(error_list[0])
                        }
                        $("#id_"+index).next().html(error_list[0]);
                        $("#id_"+index).parent().addClass('has-error');//錯誤字段邊框變紅
                    })
                }else{
                    //註冊成功
                }
            },
            error:function (err) {
                console.log(err)
            }
        })
    })
</script>
View Code

全部數據校驗經過

添加用戶記錄

def register(request):
    # if request.method=='POST':
    if request.is_ajax():
        response={"user":None,"msg":None}
        form=RegisterUser(request.POST)
        if form.is_valid():
            response['user']=form.cleaned_data.get('user')
            user=form.cleaned_data.get('user')
            pwd=form.cleaned_data.get('pwd')
            email=form.cleaned_data.get('email')
            avatar_obj=request.FILES.get('avatar')
            if avatar_obj:
                UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar=avatar_obj)
            else:
                #用戶沒有上傳頭像則不能傳入avatar參數,不傳和傳空是不同的
                UserInfo.objects.create_user(username=user, password=pwd, email=email)
        else:
            response['msg']=form.errors
        return JsonResponse(response)
    form=RegisterUser()
    return render(request,'register.html',{"form":form})
View Code

用戶校驗成功,前端跳轉到登陸界面

if (data.user){
     //用戶校驗成功,跳轉到登陸界面
    location.href='/login/';
}
View Code

django靜態文件

django有兩種靜態文件:

/static/        前端需求資源

/media/       全部用戶上傳的文件都在該文件夾中

django配置media文件件配置,在setting文件中操做

一旦配置過media,那麼FileField中上傳的文件將放置在media中

相關文章
相關標籤/搜索