利用Form組件和ajax實現的註冊

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 ]
urls.py

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))
views.py

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("兩次密碼不一致")
forms.py

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>
register.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 }
reg.css

 效果截圖

相關文章
相關標籤/搜索