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

1、登陸功能實現: 

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('/login/')
            else:
                return render(request, 'set_password.html', {'confirm_password_error': '密碼輸入不一致'})
        else:
            return render(request, 'set_password.html', {'old_password_error': '原密碼錯誤'})

    return render(request, 'set_password.html')

 其它相關配置

# 路由urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^register/', views.register),
    url(r'^login/', views.login),
    url(r'^get_code/', views.get_code),
    url(r'^home/', views.home),
    url(r'^logout/', views.logout),
    url(r'^set_password/', views.set_password),
]

# 配置文件settings.py
# 設置默認跳轉登陸路由
LOGIN_URL = '/login/'

 

相關文章
相關標籤/搜索