接着上節繼續學習,在這一節,我們將建立一個用戶注冊和身份驗證系統,讓用戶能夠注冊賬戶,進而登錄和注銷。我們將創建一個新的應用程序,其中包含與處理用戶賬戶相關的所有功能。我們還將對模型Topic稍做修改,讓每個主題都歸屬於特定用戶。
一 創建用戶賬號
1 應用程序users
我們首先使用命令startapp來創建一個名為users的應用程序:(ll_env)learning_log$ python manage.py startapp users
1.1 將應用程序users添加到settings.py中
INSTALLED_APPS = ( --snip-- # 我的應用程序 'learning_logs', 'users', )
這樣,Django將把應用程序users包含到項目中。
1.2 包含應用程序users的URL
接下來,我們需要修改項目根目錄中的urls.py,使其包含我們將為應用程序users定義的URL:
from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^users/', include('users.urls', namespace='users')), url(r'', include('learning_logs.urls', namespace='learning_logs')), ]
1.3 登錄頁面
我們首先來實現登錄頁面的功能。為此,我們將使用Django提供的默認登錄視圖,因此URL模式會稍有不同。在目錄learning_log/users/中,新建一個名為urls.py的文件,並在其中添加如下代碼:
"""為應用程序users定義URL模式""" from django.conf.urls import url from django.contrib.auth.views import login from . import views app_name='users' urlpatterns = [ # 登錄頁面 url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'), ]
1.4 模板login.html
以下是模板login.html,你應將其存儲到目錄learning_log/users/templates/users/中:
{% extends "learning_logs/base.html" %} {% block content %} {% if form.errors %} <p>Your username and password didn't match. Please try again.</p> {% endif %} <form method="post" action="{% url 'users:login' %}"> {% csrf_token %} {{ form.as_p }} <button name="submit">log in</button> <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" /> </form> {% endblock content %}
1.5 鏈接到登錄界面
下面在base.html中添加到登錄頁面的鏈接,讓所有頁面都包含它。用戶已登錄時,我們不想顯示這個鏈接,因此將它嵌套在一個{% if %}標簽中:
<p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> - <a href="{% url 'learning_logs:topics' %}">Topics</a> {% if user.is_authenticated %} Hello, {{ user.username }}. {% else %} <a href="{% url 'users:login' %}">log in</a> {% endif %} </p> {% block content %}{% endblock content %}
1.6 使用登錄界面
請訪問http://localhost:8000/admin/,如果你依然是以管理員的身份登錄的,請在頁眉上找到注銷鏈接並單擊它。注銷后,訪問http://localhost:8000/users/login/,你將看到類似於圖19-4所示的登錄頁面。輸入你在前面設置的用戶名和密碼,將進入頁面index。。在這個主頁的頁眉中,顯示了一條個性化問候語,其中包含你的用戶名。
2 注冊和注銷界面
和上面方法大概相同,就不在贅述,效果圖如下:
二 讓用戶擁有自己的數據
用戶應該能夠輸入其專有的數據,因此我們將創建一個系統,確定各項數據所屬的用戶,再限制對頁面的訪問,讓用戶只能使用自己的數據。在本節中,我們將修改模型Topic,讓每個主題都歸屬於特定用戶。這也將影響條目,因為每個條目都屬於特定的主題。我們先來限制對一些頁面的訪問。
1 使用@login_required 限制訪問
Django提供了裝飾器@login_required,讓你能夠輕松地實現這樣的目標:對於某些頁面,只允許已登錄的用戶訪問它們。裝飾器(decorator)是放在函數定義前面的指令,Python在函數運行前,根據它來修改函數代碼的行為。
--snip-- from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required from .models import Topic, Entry --snip-- @login_required def topics(request): """顯示所有的主題"""
我們首先導入了函數login_required()。我們將login_required()作為裝飾器用於視圖函數topics()——在它前面加上符號@和login_required,讓Python在運行topics()的代碼前先運行login_required()的代碼。login_required()的代碼檢查用戶是否已登錄,僅當用戶已登錄時,Django才運行topics()的代碼。如果用戶未登錄,就重定向到登錄頁面。
2 全面限制對項目“學習筆記”的訪問
在項目“學習筆記”中,我們將不限制對主頁、注冊頁面和注銷頁面的訪問,並限制對其他所有頁面的訪問。
在 下 面的learning_logs/views.py 中, 對除index() 外的每個視圖都應用了裝飾器@login_required:
@login_required def topics(request): --snip-- @login_required def topic(request, topic_id): --snip-- @login_required def new_topic(request): --snip-- @login_required def new_entry(request, topic_id): --snip-- @login_required def edit_entry(request, entry_id): --snip--
3 將數據關聯到用戶
現在,需要將數據關聯到提交它們的用戶。我們只需將最高層的數據關聯到用戶,這樣更低層的數據將自動關聯到用戶。例如,在項目“學習筆記”中,應用程序的最高層數據是主題,而所有條目都與特定主題相關聯。只要每個主題都歸屬於特定用戶,我們就能確定數據庫中每個條目的所有者。
下面來修改模型Topic,在其中添加一個關聯到用戶的外鍵。這樣做后,我們必須對數據庫進行遷移。最后,我們必須對有些視圖進行修改,使其只顯示與當前登錄的用戶相關聯的數據。
4 確定當前有哪些用戶
我們遷移數據庫時,Django將對數據庫進行修改,使其能夠存儲主題和用戶之間的關聯,下面來查看已創建的所有用戶的ID。為此,啟動一個Django shell會話,並執行如下命令:
3 遷移數據庫
知道用戶ID后,就可以遷移數據庫了。
現在可以執行遷移了。為此,在活動的虛擬環境中執行下面的命令:
驗證遷移是否成功
接下來的保護用戶主題,保護頁面,將新主題關聯到當前用戶等就不再詳細說了!今天先學到這里!