1. 程式人生 > >19-3 auth模塊

19-3 auth模塊

migration alt 裝飾器 style ons dir display ssi plugins

參考:https://www.cnblogs.com/liwenzhou/p/9030211.html

一 auth使用django默認的user表

1 auth常用方法

  1. authenticate()
  2. login()
  3. create_user()
  4. create_superuser()
  5. logout()
  6. check_password()
  7. set_password()

2 利用auth來實現登錄和註冊功能

登錄例子:

在登錄之前,在settings.py裏面必須先設置

LOGIN_URL = /login/    #
這裏配置成你項目登錄頁面的路由

否則登錄的時候默認會跳到http://127.0.0.1:8000/accounts/login/

from django.contrib import auth # 必須先導入auth


# 登錄
def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    else:
        next_url = request.GET.get("next")
        print(next_url)
        username 
= request.POST.get("username") pwd = request.POST.get("password") user_obj = auth.authenticate(request, username=username, password=pwd) if user_obj: auth.login(request, user_obj) # # 給該次請求設置了session數據,並在響應中回寫cookie if next_url: return
redirect(next_url) else: return redirect("/book_list/") else: return render(request, "login.html", {"error_msg": "用戶名或密碼錯誤"})

html頁面

技術分享圖片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <h1>登陸</h1>
 9 <a href="/reg/">註冊</a>
10 <form action="" method="post">
11     {% csrf_token %}
12     <p>
13         <input type="text" name="username">
14     </p>
15     <p>
16         <input type="password" name="password">
17     </p>
18     <p>
19         <input type="submit">
20         <span>{{ error_msg }}</span>
21     </p>
22 </form>
23 
24 </body>
25 </html>
View Code

# 註冊

from django.contrib.auth.models import User  # 創建用戶auth自帶 


def reg(request):
    if request.method == "GET":
        return render(request, "reg.html")
    else:
        username = request.POST.get("username")
        pwd = request.POST.get("password")
        user_obj = User.objects.create_user(username=username, password=pwd)  # 用auth自帶的去創建用戶,這裏用的是數據庫自帶的user表
        return redirect("/login/")

裝飾器

要想用auth裝飾器需要先導入:

from django.contrib.auth.decorators import login_required 
然後在你想要裝飾的頁面上面加上 @login_required

二 auth使用自己定義的表
1 setting.py設置
AUTH_USER_MODEL="fault_reporting.Userinfo"  # 告訴djanjo用我自己定義的用戶表,點前面的是django的項目名字,點後面的是表名

2 models.py設置,增加兩個字段

1. 必須繼承AbstractUser
from django.contrib.auth.models import AbstractUser

class UserInfo(AbstractUser):
    phone=models.CharField(max_length=11)
    avatar=models.FileField(upload_to="avatars/",default="avatars/default.png")

3 運行兩條創建的命令

python manage.py makemigrations --> 將models.py的改動記錄在小本本上

python manage.py migrate  

4 根據這個表去寫個CMS項目

目錄結構:

技術分享圖片

4.1登錄--驗證碼功能

註意:在使用驗證碼之前必須安裝pillow模塊,pip install pillow,安裝的時候如果報錯就where pip查看你的pip安裝在哪裏,然後進去相應的目錄再次安裝即可

urls.py

  url(r^login/$, views.LoginView.as_view()),
    url(r^index/$, views.index),
    url(r^vcode/$, views.vcode),   #驗證碼目錄

views.py

技術分享圖片
 1 from django.shortcuts import render, redirect, HttpResponse
 2 from django import views
 3 from django.contrib import auth
 4 import random
 5 
 6 
 7 # Create your views here.
 8 class LoginView(views.View):
 9     def get(self, request):
10         return render(request, "login.html")
11 
12     def post(self, request):
13         next_url = request.GET.get("next","/index/")
14         username = request.POST.get("username")
15         pwd = request.POST.get("password")
16         v_code=request.POST.get("vcode","").upper()  #如果用戶不寫驗證碼就是空
17         if v_code==request.session.get("v_code"):
18 
19             user_obj = auth.authenticate(username=username, password=pwd)
20             if user_obj:
21                 auth.login(request, user_obj)  # auth認證登錄
22                 return redirect(next_url)
23             else:
24                 return render(request, "login.html", {"error_msg": "用戶名或密碼錯誤"})
25         else:
26             return render(request, "login.html", {"error_msg": "驗證碼錯誤"})
27 
28 
29 # 首頁
30 def index(request):
31     return render(request, "index.html")
32 
33 
34 # 驗證碼路徑
35 def vcode(request):
36     from PIL import Image, ImageDraw, ImageFont  # 導入繪圖模塊
37     # 定義一個生成隨機顏色代碼的函數
38     def random_color():
39         return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
40 
41     # 創建一個隨機背景顏色的圖片對象
42     image_obj = Image.new(
43         "RGB",
44         (250, 35),  # 背景圖片的長和寬
45         random_color()
46     )
47     # 在該圖片對象上生成一個畫筆對象
48     draw_obj = ImageDraw.Draw(image_obj)
49     # 加載一個字體對象
50     font_obj = ImageFont.truetype(static/font/kumo.ttf, 28)  # 字體大小
51     tmp = []
52     for i in range(5):
53         l = chr(random.randint(97, 122))  # 生成隨機的小寫字母
54         u = chr(random.randint(65, 90))  # 生成隨機的大寫字母
55         n = str(random.randint(0, 9))  # 生成一個隨機的數字
56         # 從上面三個隨機選一個
57         r = random.choice([l, u, n])
58         # 將選中過的那個字符寫到圖片上
59         draw_obj.text((40 * i + 30, 0), r, fill=random_color(), font=font_obj)  # text指定的是從那開始寫位置,fill是字體顏色
60         tmp.append(r)
61 
62         v_code = "".join(tmp).upper()
63         # 將生成的驗證碼保存
64         request.session["v_code"] = v_code
65 
66         # 直接在內存中保存圖片替代io操作
67     from io import BytesIO
68     f1 = BytesIO()
69     image_obj.save(f1, format="PNG")  # 將背景圖片保存到f1裏面
70     img_data = f1.getvalue()  # 去f1取圖片
71     return HttpResponse(img_data, content_type="image/png")
View Code

login.html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>登錄</title>
 6     <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.min.css">
 7     <link rel="stylesheet" href="/static/css/mycss.css">
 8 </head>
 9 <body>
10 
11 
12 <div class="container">
13     <div class="row">
14         <div class="col-md-6 col-sm-offset-3 login-box">
15             <h3>登錄頁面</h3>
16             <form action="" method="post">
17                 {% csrf_token %}
18                 <div class="form-group">
19                     <label for="id_username">用戶名</label>
20                     <input type="text" class="form-control" id="id_username" name="username" placeholder="用戶名">
21                 </div>
22                 <div class="form-group">
23                     <label for="id_password">密碼</label>
24                     <input type="password" class="form-control" id="id_password" name="password" placeholder="密碼">
25                 </div>
26                 <div class="form-group">
27                     <label for="id_vcode" style="display: block">驗證碼</label>
28                     <input type="text" class="form-control" id="id_vcode" name="vcode" placeholder="驗證碼" style="width: 250px;display: inline-block">
29                     <img src="/vcode/" id="v-code-img" style="width: 250px;height: 35px;display: inline-block;float: right">
30                 </div>
31                 <button type="submit" class="btn btn-success" id="login-button">登陸</button>
32                 <p class="login-error">{{ error_msg }}</p>
33 
34             </form>
35         </div>
36     </div>
37 </div>
38 <script src="/static/plugins/jquery-3.3.1.min.js"></script>
39 <script src="/static/js/login.js"></script>
40 
41 </body>
42 </html>

login.js內容:

// 設置錯誤信息鼠標點擊input自動消失
$(".login-box input").focus(function () {
    $(".login-error").text("");

    }
);

// 設置驗證碼點擊變化
$("#v-code-img").click(function () {
    this.src+="?"

});

關於驗證碼的額外功能:加幹擾線和幹擾點

# # 加幹擾線
    # width = 250  # 圖片寬度(防止越界)
    # height = 35
    # for i in range(5):
    #     x1 = random.randint(0, width)
    #     x2 = random.randint(0, width)
    #     y1 = random.randint(0, height)
    #     y2 = random.randint(0, height)
    #     draw_obj.line((x1, y1, x2, y2), fill=random_color())
    #
    # # 加幹擾點
    # for i in range(40):
    #     draw_obj.point([random.randint(0, width), random.randint(0, height)], fill=random_color())
    #     x = random.randint(0, width)
    #     y = random.randint(0, height)
    #     draw_obj.arc((x, y, x+4, y+4), 0, 90, fill=random_color())

19-3 auth模塊