Django项目---- 基于Ajax和form实现注册功能

一、注册详解

1.调用模块

from django import forms
from django.forms import widgets
from .models import UserInfo
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
from django.http import JsonResponse

2.form组件自带的验证

class RegForm(forms.Form):
    #给字段加验证条件
    user=forms.CharField(max_length=8,label="用户名",
                #给input标签添加样式 widget
=widgets.TextInput(attrs={"class":"form-control"}) ) pwd=forms.CharField(min_length=4,label="密码", widget=widgets.PasswordInput(attrs={"class":"form-control"})) repeat_pwd=forms.CharField(min_length=4,label="确认密码", widget=widgets.PasswordInput(attrs={"class": "form-control"})) email=forms.EmailField(label="邮箱", widget=widgets.EmailInput(attrs={"class": "form-control"}) )
#定义一个局部钩子用于对某一字段进行验证
   def clean_user(self):
        val=self.cleaned_data.get("user")
        # val=self.cleaned_data.get("pwd")
      #验证数据库中是否已经存在该字段的数据
        ret=UserInfo.objects.filter(username=val)
        if not ret:
        #返回通过验证的数据
return val else:
        # raise 返回一个错误信息,通过 ValidationError 捕获这个错误信息,返回前端界面
raise ValidationError("该用户已存在")

#定义一个全局钩子用于校验多个字段

def clean(self):
        if self.cleaned_data.get("pwd")==self.cleaned_data.get("repeat_pwd"):
            return self.cleaned_data
        else:
            raise ValidationError("两次密码不一致!")

3.登录函数

def reg(request):
  #获取POST请求
if request.method=="POST": res={"user":None,"error_dict":None}
    #获取数据,生成form对象 form
=RegForm(request.POST)
      #通过 is_valid 进行校验
if form.is_valid(): print(form.cleaned_data) # {"user":"yuan","pwd":"12345","repeat_pwd":"12","email":"123"} print(request.FILES)         #获取用户上传的信息 user=form.cleaned_data.get("user") pwd=form.cleaned_data.get("pwd") email=form.cleaned_data.get("email") avatar=request.FILES.get("avatar") print("user",user)
        #判断用户是否上传头像
if avatar: #如果用户上传头像文件 user=UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar=avatar) else: #如果用户未上传头像,不进行avatar上传 user=UserInfo.objects.create_user(username=user,password=pwd,email=email) res["user"]=user.username else: #未通过验证,打印报错信息 print(form.errors) # {"repeat_pwd":["....",],"email":["......",]} print(form.cleaned_data) res["error_dict"]=form.errors
     #返回报错信息
return JsonResponse(res)

   # 如果是GET请求,利用form组件生成前端样式 form
=RegForm()
   # locals()将所有参数传回
return render(request,"reg.html",locals())

4.前端界面Ajax

<script>
    // 图像预览

    $("#avatar").change(function () {
        var choose_file=$(this)[0].files[0];
        var reader=new FileReader();
        reader.readAsDataURL(choose_file);

        reader.onload=function () {
             $(".avatar").attr("src",reader.result)
        }


    });


    // 注册事件
    $(".reg_btn").click(function () {
        var formdata=new FormData();
        formdata.append("user",$("#id_user").val());
        formdata.append("pwd",$("#id_pwd").val());
        formdata.append("repeat_pwd",$("#id_repeat_pwd").val());
        formdata.append("email",$("#id_email").val());
        formdata.append("avatar",$("#avatar")[0].files[0]);
        formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());


        $.ajax({
            url:"",
            type:"post",
            processData:false,
            contentType:false,
            data:formdata,
            success:function (data) {

                //console.log(data)
                if (data.user){
                    // 注册成功
                    location.href="/login/"
                }
                else {// 注册失败
                    console.log(data.error_dict);
                    // q清空错误信息
                    $("form span").html("");
                    $("form .form-group").removeClass("has-error")
                    // 加载错误信息
                    $.each(data.error_dict,function (field,error_list) {

                      if(field=="__all__"){
                          $("#id_repeat_pwd").next().html(error_list[0]).css("color",'red');
                          $("#id_repeat_pwd").parent().addClass("has-error")

                      }

                      $("#id_"+field).next().html(error_list[0]).css("color",'red');
                      $("#id_"+field).parent().addClass("has-error")

                    })
                }
            }
        })
    })

</script>

 5.配置一个对外接口

1.settings.py中添加配置
MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media")

MEDIA_URL="/media/"

2.在urls.py中添加路径
from django.conf.urls import url
from django.contrib import admin
from django.views.static import serve
from cnblog_s9 import settings
from blog import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^reg/', views.reg),

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

 

二、基于Ajax和form实现注册功能

1.from组件生成注册界面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
    <script src="/static/js/jquery-3.2.1.min.js"></script>
    <style>
        .container{
            margin-top: 100px;

        }
        #avatar{
            display: none;
        }

        .avatar{
            width: 60px;
            height: 60px;
            margin-left: 15px;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="" novalidate>

               {% for field in form %}
               <div class="form-group ">
                   <label for="">{{ field.label }}</label>
                   {{ field }} <span class="error pull-right"></span>
               </div>
               {% endfor %}
            
                <div class="form-group">
                    <label for="avatar">头像<img class="avatar" src="/static/img/default.png" alt=""></label>

                    <input type="file" id="avatar">
               </div>
               




                <input type="button" class="btn btn-default reg_btn pull-right" value="提交"><span class="error" style="color: red;margin-left: 20px"></span>
            </form>



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

{% csrf_token %}


<script>
    // 图像预览

    $("#avatar").change(function () {
        var choose_file=$(this)[0].files[0];
        var reader=new FileReader();
        reader.readAsDataURL(choose_file);

        reader.onload=function () {
             $(".avatar").attr("src",reader.result)
        }


    });


    // 注册事件
    $(".reg_btn").click(function () {
        var formdata=new FormData();
        formdata.append("user",$("#id_user").val());
        formdata.append("pwd",$("#id_pwd").val());
        formdata.append("repeat_pwd",$("#id_repeat_pwd").val());
        formdata.append("email",$("#id_email").val());
        formdata.append("avatar",$("#avatar")[0].files[0]);
        formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());


        $.ajax({
            url:"",
            type:"post",
            processData:false,
            contentType:false,
            data:formdata,
            success:function (data) {

                //console.log(data)
                if (data.user){
                    // 注册成功
                    location.href="/login/"
                }
                else {// 注册失败
                    console.log(data.error_dict);
                    // q清空错误信息
                    $("form span").html("");
                    $("form .form-group").removeClass("has-error")
                    // 加载错误信息
                    $.each(data.error_dict,function (field,error_list) {

                      if(field=="__all__"){
                          $("#id_repeat_pwd").next().html(error_list[0]).css("color",'red');
                          $("#id_repeat_pwd").parent().addClass("has-error")


                      }

                      $("#id_"+field).next().html(error_list[0]).css("color",'red');
                      $("#id_"+field).parent().addClass("has-error")


                    })



                }

            }
        })
    })

</script>

</body>
</html>
reg.html

2.views.py

from django import forms
from django.forms import widgets
from .models import UserInfo
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
class RegForm(forms.Form):

    user=forms.CharField(max_length=8,label="用户名",
                         widget=widgets.TextInput(attrs={"class":"form-control"})
                         )
    pwd=forms.CharField(min_length=4,label="密码",
                        widget=widgets.PasswordInput(attrs={"class":"form-control"}))
    repeat_pwd=forms.CharField(min_length=4,label="确认密码",
                         widget=widgets.PasswordInput(attrs={"class": "form-control"}))
    email=forms.EmailField(label="邮箱",
                         widget=widgets.EmailInput(attrs={"class": "form-control"})
    )


    def clean_user(self):
        val=self.cleaned_data.get("user")
        # val=self.cleaned_data.get("pwd")

        ret=UserInfo.objects.filter(username=val)
        if not ret:
            return val
        else:
            raise ValidationError("该用户已存在")

    def clean(self):
        if self.cleaned_data.get("pwd")==self.cleaned_data.get("repeat_pwd"):
            return self.cleaned_data
        else:
            raise ValidationError("两次密码不一致!")



from django.http import JsonResponse

def reg(request):
    if request.method=="POST":
        res={"user":None,"error_dict":None}
        form=RegForm(request.POST)
        if form.is_valid():
            print(form.cleaned_data) # {"user":"yuan","pwd":"12345","repeat_pwd":"12","email":"123"}
            print(request.FILES)

            user=form.cleaned_data.get("user")
            pwd=form.cleaned_data.get("pwd")
            email=form.cleaned_data.get("email")
            avatar=request.FILES.get("avatar")
            print("user",user)
            if avatar:
                user=UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar=avatar)
            else:
                user=UserInfo.objects.create_user(username=user,password=pwd,email=email)


            res["user"]=user.username
        else:
            print(form.errors) # {"repeat_pwd":["....",],"email":["......",]}
            print(form.cleaned_data)
            res["error_dict"]=form.errors
        return JsonResponse(res)
    form=RegForm()
    return render(request,"reg.html",locals())
Views.py注册相关

3.urls.py

from django.conf.urls import url
from django.contrib import admin
from django.views.static import serve
from cnblog_s9 import settings

from blog import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^reg/', views.reg),

# media 配置(用户个人文件)
    url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
urls.py注册相关

4.settings.py

#media文件夹,用于保存用户个人文件(头像等),可通过URL访问,相当于配置一个对外接口
MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media")

MEDIA_URL="/media/"
settings.py追加配置

 

posted @ 2018-04-16 09:40  TheLand  阅读(213)  评论(0)    收藏  举报