Django学习【第22篇】:基于Ajax实现的登录

一、需要知道的新知识点

1、刷新验证码。给src属性加一个?号。加个?会重新去请求

复制代码
        //#给验证码刷新
        $(".vialdCode_img").click(function () {
         方式一:dom方法#}
            $(this)[0].src+="?"#}
         方式二:jQuery的attr方法#}
            $(this).attr("src",$(this).attr("src")+'?')
        })
    }) 
复制代码

2、当登录成功跳转,或者注册成功跳转

 $(".register").click(function () {
            location.href = '/register/'
  });

3、超时后消失

setTimeout(foo, 3000)
function foo() {
                $(".error").html("")
            }

4、auth模块的使用

模块的导入:

from django.contrib import auth

几个使用方法:

1 、authenticate()   :验证用户输入的用户名和密码是否相同

提供了用户认证,即验证用户名以及密码是否正确,一般需要username  password两个关键字参数

user = authenticate(username='someone',password='somepassword')

2 、login(HttpRequest, user):登录  

该函数接受一个HttpRequest对象,以及一个认证了的User对象

此函数使用django的session框架给某个已认证的用户附加上session id等信息。

复制代码
from django.contrib.auth import authenticate, login
   
def my_view(request):
  username = request.POST['username']
  password = request.POST['password']
  user = authenticate(username=username, password=password)
  if user:
    login(request, user)
    # Redirect to a success page.
    ...
  else:
    # Return an 'invalid login' error message.
    ...
复制代码
复制代码

3 、logout(request)  注销用户 

该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

from django.contrib.auth import logout
   
def logout_view(request):
  logout(request)
  # Redirect to a success page.

4 、user对象的 is_authenticated()

要求:

  1、用户登录后才能访问某些页面

  2、如果用户没有登录就访问该页面的话直接跳转登录页面

  3、用户在跳转的登录界面中完成登录后,自动访问跳转到之前访问的地址

def my_view(request):
  if not request.user.is_authenticated():
    return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name

USer对象的几个方法

2.2 、创建用户:create_user 

from django.contrib.auth.models import User
user = User.objects.create_user(username='',password='',email='')

2.3 、check_password(passwd):密码检查

用户需要修改密码的时候 首先要让他输入原来的密码 ,如果给定的字符串通过了密码检查,返回 True

2.4 、修改密码: set_password() 

user = User.objects.get(username='')
user.set_password(password='')
user.save 

二、具体实现的登录

urls.py

复制代码
1 urlpatterns = [
2     url(r'^admin/', admin.site.urls),
3     url(r'^login/$', views.login),
4     url(r'^index/$', views.index),
5     url(r'^get_vaildCode_img/$', views.get_vaildCode_img),
6     url(r'^log_out/$', views.log_out),
7     
复制代码

view.py

复制代码
 1 def login(request):
 2     if request.method=="GET":
 3         return render(request, "login.html")
 4     else:
 5         username = request.POST.get("username")
 6         password = request.POST.get("password")
 7         vialdCode = request.POST.get("vialdCode")
 8         ret = {"flag":False,"error_msg":None}
 9         if vialdCode.upper() == request.session.get("keep_valid_code").upper():
10             user = auth.authenticate(username=username, password=password)
11             if user:
12                 #如果验证成功就让登录
13                 auth.login(request,user)
14                 ret["flag"] = True
15             else:
16                 ret["error_msg"] = "用户名和密码错误"
17         else:
18             ret["error_msg"] = "验证码错误"
19     return HttpResponse(json.dumps(ret))
20 
21 def index(request):
22     #验证是不是当前进来的那个用户,如果用户已经登录了就可以看到页面
23     # 如果没有登录就不让看见主页面,就直接返回登录页面
24     if not request.user.is_authenticated():
25         return redirect("/login/")
26     else:
27         return render(request, "index.html")
28 
29 def log_out(request):
30     auth.logout(request)
31     return redirect("/login/")
32 def get_vaildCode_img(request):
33     # 方式一:这样的方式吧路径写死了,只能是那一张图片
34     # import os
35     # path = os.path.join(settings.BASE_DIR,"static","image","3.jpg")
36     # with open(path,"rb") as f:
37     #     data = f.read()
38     # return HttpResponse(data)
39     # 方式二:每次都显示不同的图片,利用pillow模块,安装一个pillow模块
40     # from PIL import Image
41     # img = Image.new(mode="RGB",size=(120,40),color="green") #首先自己创建一个图片,参数size=(120,40) 代表长和高
42     # f = open("validcode.png","wb")#然后把图片放在一个指定的位置
43     # img.save(f,"png")  #保存图片
44     # f.close()
45     # with open("validcode.png","rb") as f:
46     #     data = f.read()
47     # return HttpResponse(data)
48     # 方式三:
49     # 方式二也不怎么好,因为每次都要创建一个保存图片的文件,我们可以不让吧图片保存到硬盘上,
50     # 在内存中保存,完了自动清除,那么就引入了方式三:利用BytesIO模块
51     # from io import BytesIO
52     # from PIL import Image
53     # img = Image.new(mode="RGB",size=(120,40),color="blue")
54     # f = BytesIO()  #内存文件句柄
55     # img.save(f,"png")  #保存文件
56     # data = f.getvalue()#打开文件(相当于python中的f.read())
57     # return HttpResponse(data)
58 
59     # 方式四:1、添加画笔,也就是在图片上写上一些文字
60     #         2、并且字体随机,背景颜色随机
61     from io import BytesIO
62     from PIL import Image,ImageDraw,ImageFont
63     import random
64     #随机创建图片
65     img = Image.new(mode="RGB",size=(120,40),color=(random.randint(0,255),random.randint(0,255),random.randint(0,255)))
66     draw = ImageDraw.Draw(img,"RGB")
67     # 画干扰线
68     for i in range(5):
69         x1 = random.randint(0, 120)
70         y1 = random.randint(0, 40)
71         x2 = random.randint(0, 120)
72         y2 = random.randint(0, 40)
73 
74         draw.line((x1, y1, x2, y2), fill=(random.randint(0,255),random.randint(0,255),random.randint(0,255)))
75 
76     font = ImageFont.truetype("static/font/kumo.ttf",20)  #20表示20像素
77 
78     str_list = []  #吧每次生成的验证码保存起来
79     # 随机生成五个字符
80     for i in range(5):
81         random_num = str(random.randint(0, 9))  # 随机数字
82         random_lower = chr(random.randint(65, 90))  # 随机小写字母
83         random_upper = chr(random.randint(97, 122))  # 随机大写字母
84         random_char = random.choice([random_num, random_lower, random_upper])
85         print(random_char,"random_char")
86         str_list.append(random_char)
87         # (5 + i * 24, 10)表示坐标,字体的位置
88         draw.text((5+i*24,10),random_char,(random.randint(0,255),random.randint(0,255),random.randint(0,255)),font=font)
89     print(str_list,"str_list")
90     f = BytesIO()#内存文件句柄
91     img.save(f,"png")   #img是一个对象
92     data = f.getvalue()  #读取数据并返回至HTML
93     valid_str = "".join(str_list)
94     print(valid_str,"valid_str")
95     request.session["keep_valid_code"] = valid_str   #吧保存到列表的东西存放至session中
96     return HttpResponse(data)
复制代码

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/login.css">
 10 </head>
 11 <body>
 12 <div class="container">
 13     <div class="row">
 14         <div class="col-md-1=10">
 15             <form class="form-horizontal" id="form_data" action="/login/" method="post">
 16                 {% csrf_token %}
 17                 <div class="form-group">
 18                     <label for="username" class="col-sm-2 control-label">用户名</label>
 19                     <div class="col-sm-5">
 20                         <input type="text" class="form-control" id="username" placeholder="username" name="username">
 21                     </div>
 22                 </div>
 23                 <div class="form-group">
 24                     <label for="password" class="col-sm-2 control-label">密码</label>
 25                     <div class="col-sm-5">
 26                         <input type="password" class="form-control" id="password" placeholder="password" name="password">
 27                     </div>
 28                 </div>
 29                 <div class="form-group">
 30                     <div class="row">
 31                         <div class="col-md-6 col-md-offset-1">
 32 {#                            文字部分#}
 33                             <label for="vialdCode" class="col-sm-2 control-label">验证码</label>
 34                              <div class="col-sm-5">
 35                                 <input type="text" class="form-control vialdCode_text" id="vialdCode" placeholder="验证码" name="vialdCode">
 36                             </div>
 37 {#                            图片部分#}
 38                              <div class="col-md-5">
 39                             <img class="vialdCode_img" src="/get_vaildCode_img/" alt="" width="200px" height="100px">
 40 {#                                 <a href=""></a>     #}
 41                         </div>
 42                         </div>
 43 
 44                     </div>
 45                 </div>
 46                 <div class="form-group">
 47                     <div class="col-sm-offset-2 col-sm-10">
 48                         <div class="checkbox">
 49                             <label>
 50                                 <input type="checkbox"> 下次自动登录
 51                             </label>
 52                         </div>
 53                     </div>
 54                 </div>
 55                 <div class="form-group">
 56                     <div class="col-sm-offset-2 col-sm-10">
 57                         <p>
 58                             <button type="button" class="btn btn-success login">登录</button>
 59                             <span class="error has-error"></span></p>
 60                         <p>
 61                             <button type="button" class="btn btn-primary register">注册</button>
 62                         </p>
 63                     </div>
 64                 </div>
 65             </form>
 66         </div>
 67     </div>
 68 </div>
 69 <script src="/static/jquery-3.2.1.min.js"></script>
 70 <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
 71 <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
 72 
 73 <script>
 74     $(function () {
 75         //给登录按钮增加事件
 76         $(".login").click(function () {
 77             function foo() {
 78                 $(".error").html("")
 79             }
 80 
 81             //用post的话就可以不用ajax了,ajax里面都包括了
 82             $.post({
 83                 url: '/login/',
 84                 headers: {"X-CSRFToken": $.cookie('csrftoken')},
 85                 data: $("#form_data").serialize(),
 86                 {#            contentType:'application/json',#}
 87                 success: function (data) {
 88                     var data = JSON.parse(data);
 89                     console.log(typeof data);
 90                     if (data["flag"]) {
 91                         window.location.href = '/index/'
 92                     }
 93                     else {
 94                         $(".error").html(data["error_msg"]);
 95                         setTimeout(foo, 3000)
 96                     }
 97                 }
 98             })
 99         });
100 
101         //给注册按钮增加事件
102         $(".register").click(function () {
103             window.location.href = '/register/'
104         });
105 
106         //#给验证码刷新
107         $(".vialdCode_img").click(function () {
108 {#            方式一:dom方法#}
109 {#            $(this)[0].src+="?"#}
110 {#            方式二:jQuery的attr方法#}
111             $(this).attr("src",$(this).attr("src")+'?')
112         })
113     })
114 
115 </script>
116 </body>
117 </html>
复制代码
复制代码
 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 </head>
 9 <body>
10 <h1>hello{{ request.user.username }}</h1>
11 <button><a href="/log_out/">注销</a></button>
12 </body>
13 </html>
复制代码
复制代码
 1 .container {
 2     margin-top: 100px;
 3     margin-left: 330px;
 4 }
 5 
 6 .error {
 7     color: red;
 8 }
 9 
10 .btn {
11      200px;
12 }
13 .vialdCode_img{
14      200px;
15     height: 40px;
16 }
复制代码
原文地址:https://www.cnblogs.com/kcwxx/p/10156422.html