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>
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())
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}), ]
4.settings.py
#media文件夹,用于保存用户个人文件(头像等),可通过URL访问,相当于配置一个对外接口 MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media") MEDIA_URL="/media/"

浙公网安备 33010602011771号