用戶管理
用戶數據可以說是大部分網站最重要的資產。用戶管理就是對用戶數據進行增刪改查等操作的功能,自然也就非常的重要了。
本章開始學習用戶管理的內容,首先從用戶登錄開始。
在Django中用app來區別不同功能的模塊,達到代碼隔離和複用。因爲用戶管理和博客文章的功能不同,因此需要新建一個專門的app。
進入虛擬環境,運行startapp
指令創建新的app:
python manage.py startapp userprofile
查看項目目錄,發現已經新生成了userprofile目錄及其中的文件了。
再遇表單類
用戶登錄時,需要填寫賬戶密碼等表單數據,因此又要用到Form表單類。
在userprofile
目錄中創建表單類的文件forms.py
,編寫如下代碼:
/userprofile/forms.py
# 引入表單類
from django import forms
# 引入 User 模型
from django.contrib.auth.models import User
# 登錄表單,繼承了 forms.Form 類
class UserLoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField()
在前面發表文章的模塊中,表單類繼承了forms.ModelForm
,這個父類適合於需要直接與數據庫交互的功能,比如新建、更新數據庫的字段等。如果表單將用於直接添加或編輯Django模型,則可以使用 ModelForm
來避免重複書寫字段描述。
而forms.Form
則需要手動配置每個字段,它適用於不與數據庫進行直接交互的功能。用戶登錄不需要對數據庫進行任何改動,因此直接繼承forms.Form
就可以了。
編寫視圖
用戶的登錄是比較複雜的功能,好在Django提供了封裝好的模塊供我們使用。
首先在userprofile/views.py
中寫視圖函數:
/userprofile/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from django.http import HttpResponse
from .forms import UserLoginForm
# Create your views here.
def user_login(request):
if request.method == 'POST':
user_login_form = UserLoginForm(data=request.POST)
if user_login_form.is_valid():
# .cleaned_data 清洗出合法數據
data = user_login_form.cleaned_data
# 檢驗賬號、密碼是否正確匹配數據庫中的某個用戶
# 如果均匹配則返回這個 user 對象
user = authenticate(username=data['username'], password=data['password'])
if user:
# 將用戶數據保存在 session 中,即實現了登錄動作
login(request, user)
return redirect("article:article_list")
else:
return HttpResponse("賬號或密碼輸入有誤。請重新輸入~")
else:
return HttpResponse("賬號或密碼輸入不合法")
elif request.method == 'GET':
user_login_form = UserLoginForm()
context = { 'form': user_login_form }
return render(request, 'userprofile/login.html', context)
else:
return HttpResponse("請使用GET或POST請求數據")
-
跟發表文章的表單類類似,Form對象的主要任務就是驗證數據。調用
is_valid()
方法驗證並返回指定數據是否有效的布爾值。 -
Form
不僅負責驗證數據,還可以“清洗”它:將其標準化爲一致的格式,這個特性使得它允許以各種方式輸入特定字段的數據,並且始終產生一致的輸出。一旦Form
使用數據創建了一個實例並對其進行了驗證,就可以通過cleaned_data
屬性訪問清洗之後的數據。 -
authenticate()
方法驗證用戶名稱和密碼是否匹配,如果是,則將這個用戶數據返回。 -
login()
方法實現用戶登錄,將用戶數據保存在session中。
其他的內容就跟發表文章時的技巧類似了。
什麼是session
Session在網絡應用中,稱爲**“會話控制”**,它存儲特定用戶會話所需的屬性及配置信息。
當用戶在 Web 頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去。
Session 最常見的用法就是存儲用戶的登錄數據。
詳情看這裏:Session百度百科
登錄的模板
接着寫模板文件。
創建/templates/userprofile/login.html
模板:
/templates/userprofile/login.html
{% extends "base.html" %} {% load staticfiles %}
{% block title %} 登錄 {% endblock title %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-12">
<br>
<form method="post" action=".">
{% csrf_token %}
<!-- 賬號 -->
<div class="form-group">
<label for="username">賬號</label>
<input type="text" class="form-control" id="username" name="username">
</div>
<!-- 密碼 -->
<div class="form-group">
<label for="password">密碼</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<!-- 提交按鈕 -->
<button type="submit" class="btn btn-primary">提交</button>
</form>
</div>
</div>
</div>
{% endblock content %}
內容與使用Form表單類發表新文章非常類似。唯一新知識是輸入密碼錶單的type="password"
,可以讓輸入密碼的時候顯示小圓點,避免有人偷窺。
然後我們改寫一下tempalates/header.html
,把登錄的按鈕加進去:
/tempalates/header.html
...
<ul class="navbar-nav">
...
<li class="nav-item">
<a class="nav-link" href="{% url 'article:article_list' %}">文章</a>
</li>
<!-- Django的 if 模板語句 -->
{% if user.is_authenticated %}
<!-- 如果用戶已經登錄,則顯示用戶名下拉框 -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ user.username }}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">退出登錄</a>
</div>
</li>
<!-- 如果用戶未登錄,則顯示 “登錄” -->
{% else %}
<li class="nav-item">
<a class="nav-link" href="{% url 'userprofile:login' %}">登錄</a>
</li>
<!-- if 語句在這裏結束 -->
{% endif %}
</ul>
...
這裏使用了新的模板語法:{% if … %},用來判斷用戶是否已經登錄:
- 如果用戶已經登錄,則顯示一個名字爲用戶名稱的下拉框,就像通常的社交網站一樣。
- 如果用戶未登錄,則顯示“登錄”兩個字提醒用戶可以點擊登錄。
is_authenticated
是models.User
類的屬性,用於判斷用戶是否已通過身份驗證。
url及其他設置
最後的步驟就是將app配置到項目中去。
創建userprofile/urls.py
文件:
/userprofile/urls.py
from django.urls import path
from . import views
app_name = 'userprofile'
urlpatterns = [
# 用戶登錄
path('login/', views.user_login, name='login'),
]
配置根路由my_blog/urls.py
:
/my_blog/urls.py
...
urlpatterns = [
...
# 用戶管理
path('userprofile/', include('userprofile.urls', namespace='userprofile')),
]
配置my_blog/settings.py
:
my_blog/settings.py
...
INSTALLED_APPS = [
...
'userprofile',
]
...
因爲userprofile
這個app並沒有改動model,因此不用遷移數據。
OK了,運行服務器,在admin後臺中退出登錄(找找頁面右上角),返回到文章列表頁:
點擊登錄按鈕,輸入賬號和密碼(可以故意輸錯試試會出現什麼):
點擊提交,將自動回到文章列表頁面:
大功告成。
用戶的退出
有了用戶登錄的知識後,用戶退出就很簡單了。這裏就直接給出代碼,相信你一定能看懂。
還是先添加用戶退出的視圖:
/userprofile/views.py
...
# 引入logout模塊
from django.contrib.auth import authenticate, login, logout
...
# 用戶退出
def user_logout(request):
logout(request)
return redirect("article:article_list")
然後配置/userprofile/urls.py
:
/userprofile/urls.py
...
urlpatterns = [
path('login/', views.user_login, name='login'),
# 用戶退出
path('logout/', views.user_logout, name='logout'),
]
在寫登錄的代碼時,已經給用戶退出留好了接口,因此只需要改動/templates/header.html
:
/templates/header.html
...
# 改動 href 中的鏈接指向
<a class="dropdown-item" href='{% url "userprofile:logout" %}'>退出登錄</a>
...
保存後刷新頁面,點擊下拉框中“退出登錄”選項,用戶就順利退出了。
總結
本章用到了表單類、if模板語句、用戶驗證等知識完成了用戶管理的登錄和退出。
接下來學習如何實現註冊和刪除。
- 有疑問請在杜賽的個人網站留言,我會盡快回復。
- 或Email私信我:[email protected]
- 項目完整代碼:Django_blog_tutorial
轉載請告知作者並註明出處。