1. 程式人生 > >Django 【第十七篇】Ajax實現用戶登錄

Django 【第十七篇】Ajax實現用戶登錄

主頁 settime eth ret 不讓 字符 code 建圖 script

一、需要知道的新知識點

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

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^login/$‘, views.login),
    url(r‘^index/$‘, views.index),
    url(r‘^get_vaildCode_img/$‘, views.get_vaildCode_img),
    url(r‘^log_out/$‘, views.log_out),
    

view.py

def login(request):
    if request.method=="GET":
        return render(request, "login.html")
    else:
        username = request.POST.get("username")
        password = request.POST.get("password")
        vialdCode = request.POST.get("vialdCode")
        ret = {"flag":False,"error_msg":None}
        if vialdCode.upper() == request.session.get("keep_valid_code").upper():
            user = auth.authenticate(username=username, password=password)
            if user:
                #如果驗證成功就讓登錄
                auth.login(request,user)
                ret["flag"] = True
            else:
                ret["error_msg"] = "用戶名和密碼錯誤"
        else:
            ret["error_msg"] = "驗證碼錯誤"
    return HttpResponse(json.dumps(ret))

def index(request):
    #驗證是不是當前進來的那個用戶,如果用戶已經登錄了就可以看到頁面
    # 如果沒有登錄就不讓看見主頁面,就直接返回登錄頁面
    if not request.user.is_authenticated():
        return redirect("/login/")
    else:
        return render(request, "index.html")

def log_out(request):
    auth.logout(request)
    return redirect("/login/")
def get_vaildCode_img(request):
    # 方式一:這樣的方式吧路徑寫死了,只能是那一張圖片
    # import os
    # path = os.path.join(settings.BASE_DIR,"static","image","3.jpg")
    # with open(path,"rb") as f:
    #     data = f.read()
    # return HttpResponse(data)
    # 方式二:每次都顯示不同的圖片,利用pillow模塊,安裝一個pillow模塊
    # from PIL import Image
    # img = Image.new(mode="RGB",size=(120,40),color="green") #首先自己創建一個圖片,參數size=(120,40) 代表長和高
    # f = open("validcode.png","wb")#然後把圖片放在一個指定的位置
    # img.save(f,"png")  #保存圖片
    # f.close()
    # with open("validcode.png","rb") as f:
    #     data = f.read()
    # return HttpResponse(data)
    # 方式三:
    # 方式二也不怎麽好,因為每次都要創建一個保存圖片的文件,我們可以不讓吧圖片保存到硬盤上,
    # 在內存中保存,完了自動清除,那麽就引入了方式三:利用BytesIO模塊
    # from io import BytesIO
    # from PIL import Image
    # img = Image.new(mode="RGB",size=(120,40),color="blue")
    # f = BytesIO()  #內存文件句柄
    # img.save(f,"png")  #保存文件
    # data = f.getvalue()#打開文件(相當於python中的f.read())
    # return HttpResponse(data)

    # 方式四:1、添加畫筆,也就是在圖片上寫上一些文字
    #         2、並且字體隨機,背景顏色隨機
    from io import BytesIO
    from PIL import Image,ImageDraw,ImageFont
    import random
    #隨機創建圖片
    img = Image.new(mode="RGB",size=(120,40),color=(random.randint(0,255),random.randint(0,255),random.randint(0,255)))
    draw = ImageDraw.Draw(img,"RGB")
    # 畫幹擾線
    for i in range(5):
        x1 = random.randint(0, 120)
        y1 = random.randint(0, 40)
        x2 = random.randint(0, 120)
        y2 = random.randint(0, 40)

        draw.line((x1, y1, x2, y2), fill=(random.randint(0,255),random.randint(0,255),random.randint(0,255)))

    font = ImageFont.truetype("static/font/kumo.ttf",20)  #20表示20像素

    str_list = []  #吧每次生成的驗證碼保存起來
    # 隨機生成五個字符
    for i in range(5):
        random_num = str(random.randint(0, 9))  # 隨機數字
        random_lower = chr(random.randint(65, 90))  # 隨機小寫字母
        random_upper = chr(random.randint(97, 122))  # 隨機大寫字母
        random_char = random.choice([random_num, random_lower, random_upper])
        print(random_char,"random_char")
        str_list.append(random_char)
        # (5 + i * 24, 10)表示坐標,字體的位置
        draw.text((5+i*24,10),random_char,(random.randint(0,255),random.randint(0,255),random.randint(0,255)),font=font)
    print(str_list,"str_list")
    f = BytesIO()#內存文件句柄
    img.save(f,"png")   #img是一個對象
    data = f.getvalue()  #讀取數據並返回至HTML
    valid_str = "".join(str_list)
    print(valid_str,"valid_str")
    request.session["keep_valid_code"] = valid_str   #吧保存到列表的東西存放至session中
    return HttpResponse(data)

  

template

login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/login.css">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-1=10">
            <form class="form-horizontal" id="form_data" action="/login/" method="post">
                {% csrf_token %}
                <div class="form-group">
                    <label for="username" class="col-sm-2 control-label">用戶名</label>
                    <div class="col-sm-5">
                        <input type="text" class="form-control" id="username" placeholder="username" name="username">
                    </div>
                </div>
                <div class="form-group">
                    <label for="password" class="col-sm-2 control-label">密碼</label>
                    <div class="col-sm-5">
                        <input type="password" class="form-control" id="password" placeholder="password" name="password">
                    </div>
                </div>
                <div class="form-group">
                    <div class="row">
                        <div class="col-md-6 col-md-offset-1">
{#                            文字部分#}
                            <label for="vialdCode" class="col-sm-2 control-label">驗證碼</label>
                             <div class="col-sm-5">
                                <input type="text" class="form-control vialdCode_text" id="vialdCode" placeholder="驗證碼" name="vialdCode">
                            </div>
{#                            圖片部分#}
                             <div class="col-md-5">
                            <img class="vialdCode_img" src="/get_vaildCode_img/"  width="200px" height="100px">
{#                                 <a href=""></a>     #}
                        </div>
                        </div>

                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <div class="checkbox">
                            <label>
                                <input type="checkbox"> 下次自動登錄
                            </label>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <p>
                            <button type="button" class="btn btn-success login">登錄</button>
                            <span class="error has-error"></span></p>
                        <p>
                            <button type="button" class="btn btn-primary register">註冊</button>
                        </p>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
<script src="/static/jquery-3.2.1.min.js"></script>
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>

<script>
    $(function () {
        //給登錄按鈕增加事件
        $(".login").click(function () {
            function foo() {
                $(".error").html("")
            }

            //用post的話就可以不用ajax了,ajax裏面都包括了
            $.post({
                url: ‘/login/‘,
                headers: {"X-CSRFToken": $.cookie(‘csrftoken‘)},
                data: $("#form_data").serialize(),
                {#            contentType:‘application/json‘,#}
                success: function (data) {
                    var data = JSON.parse(data);
                    console.log(typeof data);
                    if (data["flag"]) {
                        window.location.href = ‘/index/‘
                    }
                    else {
                        $(".error").html(data["error_msg"]);
                        setTimeout(foo, 3000)
                    }
                }
            })
        });

        //給註冊按鈕增加事件
        $(".register").click(function () {
            window.location.href = ‘/register/‘
        });

        //#給驗證碼刷新
        $(".vialdCode_img").click(function () {
{#            方式一:dom方法#}
{#            $(this)[0].src+="?"#}
{#            方式二:jQuery的attr方法#}
            $(this).attr("src",$(this).attr("src")+‘?‘)
        })
    })

</script>
</body>
</html>

  

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width">
    <title>Title</title>
</head>
<body>
<h1>hello{{ request.user.username }}</h1>
<button><a href="/log_out/">註銷</a></button>
</body>
</html>

  

login.css
.container {
    margin-top: 100px;
    margin-left: 330px;
}

.error {
    color: red;
}

.btn {
    width: 200px;
}
.vialdCode_img{
    width: 200px;
    height: 40px;
}

  

Django 【第十七篇】Ajax實現用戶登錄