BBS(仿博客園系統)項目02(登錄(動態生成驗證碼)、主頁搭建)

来源:https://www.cnblogs.com/suguangti/archive/2019/06/20/11061896.html
-Advertisement-
Play Games

一、登錄功能實現: html頁面: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>主頁</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/j ...


一、登錄功能實現: 

html頁面:

①login.html頁面:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄頁面</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/reg.css">
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3
                    col-sm-6 col-sm-offset-3
                    col-xs-8 col-xs-offset-2">
            <h2 class="text-center">登錄頁面</h2>
            <hr>
            {% csrf_token %}
            <div class="form-group">
                <label for="id_username">用戶名</label>
                <input type="text" id="id_username" name="username" class="form-control">
            </div>
            <div class="form-group">
                <label for="id_password">密碼</label>
                <input type="password" id="id_password" name="password" class="form-control">
            </div>
            <div class="form-group">
                <label for="id_code">驗證碼</label>
                    <div class="row">
                        <div class="col-md-6
                                    col-sm-4
                                    col-xs-4">
                            <input type="text" id="id_code" name="code" class="form-control">
                        </div>
                        <div class="col-md-6
                                    col-sm-8
                                    col-xs-8">
                            <div class="col-md-7 col-sm-7 col-xs-7">
{#                                驗證碼圖片有後端生成,通過路由獲取,寬度自適應,高度固定#}
                                <img src="/get_code/" width="100%" height="60" id="id_code_img">
                            </div>
                            <div class="col-md-5 col-sm-5 col-xs-5">
                                <span>看不清?點擊圖片換一張</span>
                            </div>

                        </div>
                    </div>
            </div>
            <button class="btn btn-primary" id="id_submit">登錄</button>
{#            此處顯示錯誤提示,has-error是為了設置樣式而設的類#}
            <span class="has-error" id="id_error"></span>
        </div>
    </div>
</div>
<script>
    // 驗證碼圖片被點擊,就在該src後面自動拼接一個問號?,後端只要發現路由有變化就會重新生成驗證碼圖片
    $('#id_code_img').on('click',function () {
        let old_path = $(this).attr('src');
        $(this).attr('src',old_path+'?')
    });
    // 使用ajax提交數據,動態刷新login頁面局部信息
    $('#id_submit').on('click',function () {
        $.ajax({
            url: '',
            type: 'post',
            data: {
                'username':$('#id_username').val(),
                'password':$('#id_password').val(),
                'code':$('#id_code').val(),
                'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val(),
                //也可以使用這個
                {#'csrfmiddlewaretoken': '{{ csrf_token }}',#}  
            },
            success:function (data) {
                // 登錄成功
                if (data.code==100){
                    location.href = data.url
                }
                // 登錄失敗,將error的span標簽加上內容
                else {$('#id_error').html(data.msg)}
            }

        })
    })
</script>
</body>
</html>
②set_password.html頁面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BBS</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/reg.css">
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h2 class="text-center">修改密碼</h2>
            <hr>
            <form action="" method="post">
                {% csrf_token %}
                <div class="form-group">
                    <label for="id_username">用戶名</label>
                    <input type="text" class="form-control" name="username" id="id_username" disabled value="{{ request.user.username }}">
                </div>
                <div class="form-group">
                    <label for="id_old_password">原密碼</label>
                    <input type="password" class="form-control" name="old_password" id="id_old_password">
                    <span class="has-error" id="id_old_password_error">{{ old_password_error }}</span>
                </div>
                <div class="form-group">
                    <label for="id_password">密碼</label>
                    <input type="password" class="form-control" name="password" id="id_password">
                </div>
                <div class="form-group">
                    <label for="id_confirm_password">確認密碼</label>
                    <input type="password" class="form-control" name="confirm_password" id="id_confirm_password">
                    <span class="has-error" id="id_confirm_password_error">{{ confirm_password_error }}</span>
                </div>
                <div class="form-group">
                <button class="btn btn-primary" id="id_submit">提交修改</button>
                </div>
            </form>
        </div>
    </div>
</div>
<script>
    $('input').on('focus',function () {
        $(this).next().html('')
    })
</script>
</body>
</html>
③home.html頁面(導航條搭建)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主頁</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">BBS</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">文章 <span class="sr-only">(current)</span></a></li>
                <li><a href="#">隨筆</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                {% if request.user.is_authenticated %}
                <li><a href="">歡迎您</a></li>
                <li><a href="#">{{ request.user.username }}</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">更多操作 <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="/set_password/">密碼修改</a></li>
                        <li><a href="#">修改頭像</a></li>

                        <li role="separator" class="divider"></li>
                        <li><a href="/logout/">註銷</a></li>
                    </ul>
                </li>
                {% else %}
                    <li><a href="/login/">登錄</a></li>
                    <li><a href="/register/">註冊</a></li>
                {% endif %}
            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
    <div class="row">

    </div>

</div>
</body>
</html>
主頁面導航條搭建
④css樣式文件
#myform span {
    color: red;
}

.has-error {
    color: red;
}

views.py視圖函數

①隨機驗證碼生成:
# 隨機生成顏色代碼
def get_random():
    return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)

# 從PIL(需下載)導入Image用來生成圖片,ImageDraw在圖片上寫字,ImageFont圖片上的字體樣式
from PIL import Image,ImageDraw,ImageFont,ImageFilter
from io import BytesIO  # 幫我們保存數據,同時取得時候以二進位形式返回給我

# 隨機生成驗證碼圖片
def get_code(request):
    # 推導步驟1,打開本地文件發送二進位數據給前端傳code圖片
    '''
    with open(r'D:\Django\BBS01\app01\static\avatar\code1.jpg', 'rb') as f:
        data = f.read()
    return HttpResponse(data)
    '''
    # 推導步驟2,生成動態圖片發送二進位數據
    ''''
    # img_obj = Image.new('RGB', (180, 35), 'red')
    # img_obj = Image.new('RGB', (180, 60), (128, 128, 128))
    img_obj = Image.new('RGB', (180, 60), get_random())
    # 先保存成文件
    with open('demo.png', 'wb') as f1:
        img_obj.save(f1)
    with open('demo.png', 'rb') as f2:
        return HttpResponse(f2.read())
    '''
    # 推導步驟3,圖片存放不再依賴於文件的形式
    '''
    img_obj = Image.new('RGB', (180, 60), get_random())
    ## 生成一個BytesIO對象
    io_obj = BytesIO()  # 可以當做一個文件句柄f使用
    img_obj.save(io_obj, 'png')  # 將生成的圖片數據存入記憶體管理器中,註意後面要指定圖片尾碼名
    return HttpResponse(io_obj.getvalue())
    # 通過io_obj.getvalue()來取出,取出的是二進位形式數據
    '''
    # 最後在圖片上‘畫’上字母和數字
    img_obj = Image.new('RGB', (180, 60), get_random())
    # 生成一個畫筆對象
    img_draw = ImageDraw.Draw(img_obj)
    # 生成一個字體對象
    img_font = ImageFont.truetype('app01/static/code2.ttf', 48)
    # 隨機驗證碼:數字+字母
    # 先定義一個code變數來記錄生成的碼,用於後面的校驗
    code = ''
    for i in range(4):
        number = str(random.randint(0, 9))
        upper = chr(random.randint(97, 122))
        lower = chr(random.randint(65, 90))
        temp_code = random.choice([number, upper, lower])
        # 將隨機的碼寫到圖片上:
        img_draw.text((20+i*38, 10), temp_code, get_random(), img_font)
        #                坐標位置  隨機生成的碼  隨機生成的顏色 碼的字體樣式
        # 註意這裡需要一個字一個字的往圖片里寫碼,每次寫坐標要向右移動,這樣碼才不會疊加在一起
        code += temp_code
    # 此時img_obj圖片對象裡面就包含了4個隨機碼
    print(code)
    # 將code字元串存入session中,用於後面登錄的校驗
    request.session['code'] = code
    # 生成一個io對象幫助我們動態存隨機生成的圖片
    io_obj = BytesIO()
    # 設置圖片模糊(瞭解)
    # img_obj = img_obj.filter(ImageFilter.BLUR)
    img_obj.save(io_obj, 'png')  # 將圖片對象保存到io對象中
    return HttpResponse(io_obj.getvalue())
②登錄相關視圖函數,包括登錄、註銷、設置密碼、主頁簡單搭建
# 登錄
def login(request):
    back_dic = {'code': 100, 'msg': ''}
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        code = request.POST.get('code')
        # 先校驗驗證碼是否輸入正確
        if request.session.get('code').lower() == code.lower():
            # 通過auth.authenticate()方法,對用戶進行認證
            user_obj = auth.authenticate(username=username, password=password)
            if user_obj:
                # 如果user_obj存在,則說明用戶名和密碼正確,即表示登錄成功
                auth.login(request, user_obj)  # 記錄登錄狀態
                back_dic['msg'] = '登錄成功'
                back_dic['url'] = '/home/'
            else:
                back_dic['code'] = 102
                back_dic['msg'] = '用戶名或密碼錯誤'
        else:
            back_dic['code'] = 101
            back_dic['msg'] = '驗證碼錯誤'
        return JsonResponse(back_dic)
    return render(request, 'login.html')

# 註銷
def logout(request):
    auth.logout(request)
    return redirect('/home/')

# 主頁
def home(request):
    return render(request, 'home.html')

# 修改密碼
from django.contrib.auth.decorators import login_required
@login_required
def set_password(request):
    if request.method == 'POST':
        old_password = request.POST.get('old_password')
        password = request.POST.get('password')
        confirm_password = request.POST.get('confirm_password')
        if request.user.check_password(old_password):  # 如果密碼檢查通過
            if password == confirm_password:
                request.user.set_password(password)
                request.user.save()
                return redirect(
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Java語言的環境搭建 1.什麼是JDK和JRE? JDK(Java Development Kit:Java開發工具包): JDK是提供給Java開發人員使用的,其中包含了java的開發工具,也包括了JRE。所以安裝了JDK,就不用再單獨安裝JRE了。其中的開發工具有編譯工具(javac.exe) ...
  • 好久不見,風水輪流轉,我竟然寫寫寫python了 近日有個小需求,要求收集統計一些信息上報,並直接在後臺控制台列印,寫入日誌 為了美觀,需要以表格形式展現數據,形如 雖說可以用 prettytable 實現這個效果,不過還得安裝這個庫,需求比較簡單就不考慮安裝第三方依賴了,所以得自己寫 照著這個圖, ...
  • 分析出現no Session錯誤的原因以及給出解決方案: 使用SpringMVC + JSON數據返回時,經常會出現no Session的錯誤: 報錯原因:因為懶載入在提取關聯對象的屬性值的時候發現EntityManager已經被關閉,就報no session錯誤。 控制器類中的方法上添加了@Res ...
  • 策略模式:定義了不同的演算法,分別分裝起來,讓他們可以互相替換,即使演算法變化了,也不會影響到使用演算法的用戶 首先定義一個抽象演算法類,有兩個類繼承了這個抽象類,重寫了AlgorithmInterface()方法 用一個context類來維護對抽象演算法類Strategy對象的引用(重點) 測試類1 但是從 ...
  • 在 Spring Boot 中集成 Shiro,並使用 JWT 進行介面認證。 為了統一對 Token 進行過濾,所以自定義了一個 過濾器。 期間遇到了以下幾個問題,這裡逐一進行記錄,以備日後查閱。 問題一:JwtTokenFilter 無法使用 @Autowired 因為自定義了一個 JWT To ...
  • IDEA設置取消自動顯示參數提示 最近在使用IDEA的過程中,發現方法中一直顯示形參名的提示,無法選中,也無法刪除,基於不同人的使用習慣不同,有的人不喜歡這種提示,我也在網上尋找各種解決方案,由於搜索關鍵詞不對,一直沒能解決,不過好基友及時幫助,順利解決,多謝我的大副。 取消參數提示之前,我的方法中 ...
  • 關於django中的APPEND_SLASH 它是啥? 看變數名大概能知道做什麼,就是添加斜線,用路由系統那裡。 路由文件,只寫了路由關係代碼 APPEND_SLASH這個常量預設為True,就是假如你沒有添加斜線,他會幫你添加上(總體是這樣,具體得看源碼怎麼寫的了) 執行命名行代碼啟動django ...
  • 涉及Dynamics ax 行業已經好幾年了,準備總結一些有用的處理方法供大家來參考 首先先介紹下Computed column技術,該技術是微軟在AX2012版本中提供的新技術,可以讓SQL語句在AX view中使用,這樣就可以將想要的值拼接在一條交易記錄上,這樣就可以針對數據進行批量處理,所以想 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...