1、註冊相關的知識點css
一、Form組件html
咱們通常寫Form的時候都是把它寫在views視圖裏面,那麼他和咱們的視圖函數也不影響,咱們能夠吧它單另拿出來,在應用下面建一個forms.py的文件來存放python
二、局部鉤子函數jquery
def clean_username(self): username = self.cleaned_data.get("username") valid = models.UserInfo.objects.filter(username = username).first() if valid: raise ValidationError("用戶名已存在") return username
三、全局鉤子函數git
#自定義全局鉤子:驗證兩次密碼是否一致 def clean(self): if self.cleaned_data.get("password") == self.cleaned_data.get("password_again"): return self.cleaned_data else: raise ValidationError("兩次密碼不一致")
四、 jQuery的屬性操做相關的ajax
attr:
一個參數是獲取屬性的值,兩個參數是設置屬性值
removeAttr(屬性名):
刪除屬性值
prop:
適應於屬性的返回值是布爾類型的(單選,反選,取消的例子)
removePorp:
刪除屬性的值
五、循環的兩種方式:數據庫
$.each(數組/對象,function(i,v){})
$("div").each(function(i,v){})
六、css中的三種隱藏:django
1、display:none 隱藏全部內容
2、visibility:hidden 隱藏內容 3、overflow:hidden 隱藏溢出內容 三者都是用來隱藏的: 區別在於: visibility雖然隱藏了,可是被隱藏的內容依然佔據這空間,這段隱藏了的內容卻保留空間的位置會在網頁中顯示空白
而display:隱藏了不佔用空間 咱們在註冊的時候不用display:none,否則選擇文件的那個功能就沒有了,咱們能夠吧透明度
七、提交二進制數據用FormDatajson
var formData=new FormData(); formData.append("username",$("#id_username").val());
formData.append("email",$("#id_email").val()); formData.append("tel",$("#id_tel").val());
formData.append("password",$("#id_password").val()); formData.append("password_again",$("#id_password_again").val()); formData.append("avatar_img",$("#avatar")[0].files[0]);
記得要加上bootstrap
contentType:false processData:false
八、能夠用下面的方法判斷是什麼請求
if request.ajax(): #若是ajax請求 if request,method=="POST": #若是是POST請求
九、上傳文件有一個固定的配置參數media,和static類似 但又不一樣
步驟以下:
- 首先在settings中配置:
# ============media配置=============== MEDIA_URL="/media/" #別名 MEDIA_ROOT=os.path.join(BASE_DIR,"app01","media","uploads") #具體路徑
- 在url中配置
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
用處:
用處一:
----- avatar = models.FileField(verbose_name='頭像', upload_to='avatar', default="/avatar/default.png") 會把接收的文件放在media指代的路徑與upload_to的拼接:BASE_DIR+blog+media+uploads+avatar/a.png avatar字段在數據庫中保存的是:avatar/a.png
用處二:
------ <img src="/media/avatar/a.png">
若是上傳成功會把圖片自動保存在這裏
十、頭像圖片預覽
//頭像預覽 $(".avatar_file").change(function () { var ele_file = $(this)[0].files[0]; //當前選中的文件 var reader = new FileReader(); reader.readAsDataURL(ele_file); //對應找到打開的url reader.onload=function () { {# 方式一#} $(".avatar_img").attr("src",this.result) ; //this.result是上面找到的url {# 方式二#} {# $(".avatar_img")[0].src=this.result; //設置圖片屬性#} } })
十一、form自動生成的錯誤信息
當你定義了全局鉤子的時候,並且正好出現你的那個全局鉤子函數中的錯(好比兩次密碼輸入不一致),這樣你打印錯誤信息的時候
會有一個__all__對象,這個就是你設置的全局鉤子生成的。
因此還要單獨判斷一下,如今全局鉤子只有一個,你能夠這樣判斷,可是,當全局鉤子多的時候就得一個一個分開來判斷
if (i=="__all__"){ $("#id_password_again").after($span) }
2、具體實現註冊操做
urls.py
1 from django.conf.urls import url 2 from django.contrib import admin 3 from app01 import views 4 from django.conf import settings 5 from django.views.static import serve 6 urlpatterns = [ 7 url(r'^admin/', admin.site.urls), 8 url(r'^login/$', views.login), 9 url(r'^index/$', views.index), 10 url(r'^get_vaildCode_img/$', views.get_vaildCode_img), 11 url(r'^log_out/$', views.log_out), 12 13 url(r'^register/$', views.register), 14 url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}), 15 ]
views.py
1 def register(request): 2 if request.method=="GET": 3 form = RegisterForm() 4 return render(request,"register.html",{"form":form}) 5 else: 6 form = RegisterForm(data=request.POST) 7 regresponse = {"user":None,"msg_errors":None} 8 if form.is_valid(): 9 username = form.cleaned_data.get("username") 10 password = form.cleaned_data.get("password") 11 tel = form.cleaned_data.get("tel") 12 avatar_img = request.FILES.get("avatar_img") 13 print(">>>",username,password,tel) 14 models.UserInfo.objects.create_user(username = username,password=password,tel=tel,avatar=avatar_img) 15 regresponse["user"] = username 16 else: 17 print("form.errors",form.errors) 18 regresponse["msg_errors"]=form.errors 19 return HttpResponse(json.dumps(regresponse))
forms.py
1 #!usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from app01 import models 4 from django.forms import Form 5 from django.forms import widgets 6 from django.forms import fields 7 from django.core.validators import ValidationError 8 from django.core.validators import RegexValidator 9 class RegisterForm(Form): 10 username = fields.CharField( 11 required=True, 12 max_length=16, 13 min_length=3, 14 error_messages={ 15 "required": "用戶名不能爲空", 16 "max_length": "長度不能大於16", 17 "min_length": "長度不能小於3", 18 }, 19 widget=widgets.TextInput({"placeholder":"請您輸入用戶名","class":"form-control"}) 20 ) 21 password = fields.CharField( 22 required=True, 23 max_length=16, 24 min_length=3, 25 error_messages={ 26 "required": "密碼不能爲空", 27 "max_length": "長度不能大於16", 28 "min_length": "長度不能小於3", 29 }, 30 widget=widgets.PasswordInput({"placeholder":"請您輸入數字與字母組合的密碼","class":"form-control"}) 31 ) 32 password_again = fields.CharField( 33 required=True, 34 max_length=16, 35 min_length=3, 36 error_messages={ 37 "required": "密碼不能爲空", 38 "max_length": "長度不能大於16", 39 "min_length": "長度不能小於3", 40 }, 41 widget=widgets.PasswordInput({"placeholder": "請您再次輸入密碼", "class": "form-control"}) 42 ) 43 email = fields.EmailField( 44 required=True, 45 error_messages={ 46 "required":"郵箱不能爲空", 47 "invalid":"郵箱格式有誤" 48 }, 49 widget = widgets.EmailInput({"placeholder": "請輸入您的郵箱", "class": "form-control"}) 50 ) 51 tel = fields.CharField( 52 required=True, 53 max_length=11, 54 min_length=11, 55 error_messages={ 56 "required":"手機號碼不能爲空", 57 "max_length":"長度必須是11位,請你正確輸入", 58 "min_length":"長度必須是11位,請你正確輸入", 59 }, 60 validators=[RegexValidator("\d+","密碼只能是數字")], 61 widget=widgets.TextInput({"placeholder": "請您輸入你的電話,要求11位哦", "class": "form-control"}) 62 ) 63 64 #自定義用戶名驗證:局部鉤子 65 def clean_username(self): 66 username = self.cleaned_data.get("username") 67 valid = models.UserInfo.objects.filter(username = username).first() 68 if valid: 69 raise ValidationError("用戶名已存在") 70 return username 71 #自定義密碼驗證: 72 def clean_password(self): 73 password = self.cleaned_data.get("password") 74 if password.isdigit(): 75 raise ValidationError("密碼不能是純數字") 76 else: 77 return password 78 #自定義全局鉤子:驗證兩次密碼是否一致 79 def clean(self): 80 if self.cleaned_data.get("password") == self.cleaned_data.get("password_again"): 81 return self.cleaned_data 82 else: 83 raise ValidationError("兩次密碼不一致")
template
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width"> 7 <title>Title</title> 8 <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> 9 <link rel="stylesheet" href="/static/css/reg.css"> 10 </head> 11 <body> 12 {#導航條#} 13 <nav class="navbar navbar-inverse navbar-fixed-top"> 14 <div class="container pull-left"> 15 <!-- Brand and toggle get grouped for better mobile display --> 16 <div class="navbar-header"> 17 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" 18 data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> 19 <span class="sr-only">Toggle navigation</span> 20 <span class="icon-bar"></span> 21 <span class="icon-bar"></span> 22 <span class="icon-bar"></span> 23 </button> 24 <a class="navbar-brand" href="#">博客園</a> 25 </div> 26 27 <!-- Collect the nav links, forms, and other content for toggling --> 28 <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> 29 <ul class="nav navbar-nav"> 30 <li class="active c1"><a href="#">首頁 <span class="sr-only">(current)</span></a></li> 31 <li class="active c1"><a href="#">登陸</a></li> 32 <li class="active c1"><a href="#">註冊</a></li> 33 <li class="active c1"><a href="#">幫助</a></li> 34 </ul> 35 </div><!-- /.navbar-collapse --> 36 </div><!-- /.container-fluid --> 37 </nav> 38 <h2>註冊新用戶</h2> 39 <hr> 40 <div class="container"> 41 <div class="row left"> 42 <div class="col-md-6 col-md-offset-1"> 43 <form action="/register/" method="post" novalidate enctype="multipart/form-data"> 44 {% csrf_token %} 45 <div class="form-group"> 46 <label for="password" class="control-label">用戶名:</label> 47 <div>{{ form.username }}<span></span></div> 48 </div> 49 <div class="form-group"> 50 <label for="password" class="control-label">密碼:</label> 51 <div>{{ form.password }}<span></span></div> 52 </div> 53 <div class="form-group"> 54 <label for="password" class="control-label">確認密碼:</label> 55 <div>{{ form.password_again }}<span></span></div> 56 </div> 57 <div class="form-group"> 58 <label for="email" class="control-label">郵箱:</label> 59 <div>{{ form.email }}<span></span></div> 60 </div> 61 <div class="form-group"> 62 <label for="tel" class="control-label">手機號:</label> 63 <div>{{ form.tel }}<span></span></div> 64 </div> 65 <div class="form-group avatar"> 66 <label for="avatar">頭像:</label> 67 <img src="/static/image/default.png" alt="" class="avatar_img"> 68 <input type="file" id="avatar" name="avatar_file" class="avatar_file"> 69 </div> 70 <button type="button" class="btn btn-primary registr_btn">註冊</button><span class="xxx"></span> 71 </form> 72 </div> 73 </div> 74 <div class="right"> 75 <img src="/static/image/rigth.png" alt=""> 76 </div> 77 </div> 78 79 <script src="/static/jquery-3.2.1.min.js"></script> 80 <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> 81 <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script> 82 <script> 83 $(function () { 84 //給註冊按鈕增長事件 85 $(".registr_btn").click(function () { 86 var formData=new FormData(); 87 formData.append("username",$("#id_username").val()); 88 formData.append("email",$("#id_email").val()); 89 formData.append("tel",$("#id_tel").val()); 90 formData.append("password",$("#id_password").val()); 91 formData.append("password_again",$("#id_password_again").val()); 92 formData.append("avatar_img",$("#avatar")[0].files[0]); 93 console.log("=========",formData); 94 95 //先清除錯誤信息 96 $(".pull-right").html(""); 97 $(".pull-right").parent().removeClass("has-error"); 98 $.ajax({ 99 url:"/register/", 100 type:"POST", 101 headers: {"X-CSRFToken": $.cookie('csrftoken')}, 102 data:formData, 103 contentType:false, 104 processData:false, 105 success:function (data) { 106 {# console.log(data);#} 107 var data = JSON.parse(data); 108 if(data["user"]){ //或者也能夠用data.user 109 $(".xxx").html("註冊成功"); 110 window.location.href="/login/"; 111 } 112 else { 113 console.log(data.msg_errors); //拿到的是全部的錯誤信息 114 $.each(data.msg_errors,function (i,v) { 115 console.log(i,v); 116 $span = $("<span>");//建立一個span標籤,方便提示錯誤信息的時候用 117 $span.addClass("pull-right").css("color","red"); //設置樣式居右而且字體顏色爲紅色 118 $span.html(v[0]);//設置span裏面的字體 119 $("#id_"+i).after($span).parent().addClass("has-error");//吧span標籤放到每一個input的後面顯示而且讓他的父親變紅,增長一個has-error的類 120 121 if (i=="__all__"){ 122 $("#id_password_again").after($span) 123 } 124 }); 125 } 126 } 127 }) 128 }); 129 130 //頭像預覽 131 $(".avatar_file").change(function () { 132 var ele_file = $(this)[0].files[0]; //當前選中的文件 133 var reader = new FileReader(); 134 reader.readAsDataURL(ele_file); //對應找到打開的url 135 reader.onload=function () { 136 {# 方式一#} 137 $(".avatar_img").attr("src",this.result) ; //this.result是上面找到的url 138 {# 方式二#} 139 {# $(".avatar_img")[0].src=this.result; //設置圖片屬性#} 140 } 141 }) 142 }) 143 </script> 144 </body> 145 </html>
1 .c1 { 2 margin-right: 10px; 3 } 4 5 h2 { 6 margin-top: 100px; 7 margin-left: 280px; 8 } 9 .left{ 10 position: relative; 11 } 12 .right{ 13 width: 270px; 14 height: 294px; 15 position: absolute; 16 top: 197px; 17 left: 886px; 18 } 19 .registr_btn{ 20 width: 100px; 21 margin-left: 200px; 22 } 23 .avatar{ 24 position: relative; 25 width: 70px; 26 height: 70px; 27 } 28 .avatar_img,.avatar_file{ 29 position: absolute; 30 width: 70px; 31 height: 70px; 32 top: 0; 33 left: 46px; 34 } 35 .avatar_file{ 36 opacity: 0; 37 }
效果截圖