python初試六

chatGPT發表於2023-12-28

之前瞭解了:


建立Django專案

資料庫

模板

表格提交

admin管理頁面

上面的功能模組允許我們做出一個具有互動性的站點,但無法驗證使用者的身份。我們這次瞭解使用者驗證部分。透過使用者驗證,我們可以根據使用者的身份,提供不同的服務。


一個Web應用的使用者驗證是它的基本組成部分。我們在使用一個應用時,總是從“登入”開始,到“登出”結束。另一方面,使用者驗證又和網站安全、資料庫安全息息相關。HTTP協議是無狀態的,但我們可以利用儲存在客戶端的cookie或者儲存在伺服器的session來記錄使用者的訪問。 


Django有管理使用者的模組,即django.contrib.auth。你可以在mysite/settings.py裡看到,這個功能模組已經註冊在INSTALLED_APPS中。利用該模組,你可以直接在邏輯層面管理使用者,不需要為使用者建立模型,也不需要手工去實現會話。


建立使用者


你可以在admin頁面直接看到使用者管理的對話方塊,即Users。從這裡,你可以在這裡建立、刪除和修改使用者。點選Add增加使用者daddy,密碼為daddyiscool。


在admin頁面下,我們還可以控制不同使用者組對資料庫的訪問許可權。我們可以在Groups中增加使用者組,設定使用者組對資料庫的訪問許可權,並將使用者加入到某個使用者組中。


在這一章節中,我們創立一個新的app,即users。下文的模板和views.py,都針對該app。


使用者登入


我們建立一個簡單的表格。使用者透過該表格來提交登陸資訊,並在Django伺服器上驗證。如果使用者名稱和密碼正確,那麼登入使用者。


我們首先增加一個登入表格:


<form role="form" action="/login" method="post">

      <label>Username</label>

      <input type="text" name='username'>

      <label>Password</label>

      <input name="password" type="password">

      <input type="submit" value="Submit">

 </form>


我們在views.py中,定義處理函式user_login(),來登入使用者:


# -*- coding: utf-8 -*-

from django.shortcuts import render, redirect

from django.core.context_processors import csrf

from django.contrib.auth import *


def user_login(request):

    '''

    login

    '''

    if request.POST:

        username = password = ''

        username = request.POST.get('username')

        password = request.POST.get('password')

        user     = authenticate(username=username, password=password)

        if user is not None and user.is_active:

                login(request, user)

                return redirect('/')

    ctx = {}

    ctx.update(csrf(request))

    return render(request, 'login.html',ctx)


上面的authenticate()函式,可以根據使用者名稱和密碼,驗證使用者資訊。而login()函式則將使用者登入。它們來自於django.contrib.auth。


作為替換,我們可以使用特別的form物件,而不自行定義表格。這將讓程式碼更簡單,而且提供一定的完整性檢驗。


登出


有時使用者希望能銷燬會話。我們可以提供一個登出的URL,即/users/logout。登入使用者訪問該URL,即可登出。在views.py中,增加該URL的處理函式:


# -*- coding: utf-8 -*-

from django.shortcuts import redirect


def user_logout(request):

    '''

    logout

    URL: /users/logout

    '''

    logout(request)

    return redirect('/')


我們修改urls.py,讓url對應user_logout()。訪問,就可以登出使用者。


views.py中的使用者

上面說明了如何登入和登出使用者,但還沒有真正開始享受使用者驗證帶來的好處。使用者登陸的最終目的,就是為了讓伺服器可以區別對待不同的使用者。比如說,有些內容只能讓登陸使用者看到,有些內容則只能讓特定登陸使用者看到。我們下面將探索如何實現這些效果。


在Django中,對使用者身份的檢驗,主要是在views.py中進行。views.py是連線模型和檢視的中間層。HTTP請求會轉給views.py中的對應處理函式處理,併發回回復。在views.py的某個處理函式準備HTTP回覆的過程中,我們可以檢驗使用者是否登陸。根據使用者是否登陸,我們可以給出不同的回覆。最原始的方式,是使用if式的選擇結構: 


# -*- coding: utf-8 -*-

from django.http import HttpResponse


def diff_response(request):

    if request.user.is_authenticated():

        content = "<p>my dear user</p>"

    else:

        content = "<p>you wired stranger</p>"

    return HttpResponse(content)


可以看到,使用者的登入資訊包含在request.user中,is_authenticated()方法用於判斷使用者是否登入,如果使用者沒有登入,那麼該方法將返回false。該user物件屬於contrib.auth.user型別,還有其它屬性可供使用,比如


在Django中,我們還可以利用裝飾器,根據使用者的登入狀況,來決定views.py中處理函式的顯示效果。相對於上面的if結構,裝飾器使用起來更加方便。下面的user_only()是views.py中的一個處理函式。


from django.contrib.auth.decorators import login_required

from django.http import HttpResponse


@login_required

def user_only(request):

    return HttpResponse("<p>This message is for logged in user only.</p>")


注意上面的裝飾器login_required,它是Django預設的裝飾器。user_only()的回覆結果只能被登入使用者看到,而未登入使用者將被引導到其他頁面。


Django中還有其它的裝飾器,用於修飾處理函式。相應的http回覆,只能被特殊的使用者看到。比如user_passes_test,允許的使用者必須滿足特定標準,而這一標準是可以使用者自定義的。比如下面,在views.py中增添: 


from django.contrib.auth.decorators import user_passes_test

from django.http import HttpResponse

def name_check(user):

    return user.get_username() == 'vamei'


@user_passes_test(name_check)

def specific_user(request):

    return HttpResponse("<p>for Vamei only</p>")


裝飾器帶有一個引數,該引數是一個函式物件name_check。當name_check返回真值,即使用者名稱為vamei時,specific_user的結果才能被使用者看到。


模板中的使用者


進一步,使用者是否登陸這一資訊,也可以直接用於模板。比較原始的方式是把使用者資訊直接作為環境資料,提交給模板。然而,這並不是必須的。事實上,Django為此提供了捷徑:我們可以直接在模板中呼叫使用者資訊。比如下面的模板:


{% if user.is_authenticated %}

  <p>Welcome, my genuine user, my true love.</p>

{% else %}

  <p>Sorry, not login, you are not yet my sweetheart. </p>

{% endif %}


不需要環境變數中定義,我們就可以直接在模板中引用user。這裡,模板中呼叫了user的一個方法,is_authenticated,將根據使用者的登入情況,返回真假值。需要注意,和正常的Python程式不同,在Django模板中呼叫方法並不需要後面的括號。


使用者註冊


我們上面利用了admin管理頁面來增加和刪除使用者。這是一種簡便的方法,但並不能用於一般的使用者註冊的情境。我們需要提供讓使用者自主註冊的功能。這可以讓站外使用者提交自己的資訊,生成自己的賬戶,並開始作為登陸使用者使用網站。


使用者註冊的基本原理非常簡單,即建立一個提交使用者資訊的表格。表格中至少包括使用者名稱和密碼。相應的處理函式提取到這些資訊後,建立User物件,並存入到資料庫中。


我們可以利用Django中的UserCreationForm,比較簡潔的生成表格,並在views.py中處理表格:


from django.contrib.auth.forms import UserCreationForm

from django.shortcuts import render, redirect

from django.core.context_processors import csrf


def register(request): 

    if request.method == 'POST': 

        form = UserCreationForm(request.POST) 

        if form.is_valid(): 

            new_user = form.save() 

        return redirect("/") 

    else:

        form = UserCreationForm()

        ctx = {'form': form}

        ctx.update(csrf(request))       

        return render(request, "register.html", ctx)


相應的模板register.html如下:


<form action="" method="post">

   {% csrf_token %}

   {{ form.as_p }}

   <input type="submit" value="Register">

</form>


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70026630/viewspace-3002008/,如需轉載,請註明出處,否則將追究法律責任。

相關文章