1. 程式人生 > >【day 15】python程式設計:從入門到實踐學習筆記-基於Django框架的Web開發-使用者賬戶(二)

【day 15】python程式設計:從入門到實踐學習筆記-基於Django框架的Web開發-使用者賬戶(二)

學習筆記目錄

第十九章 使用者賬戶(二)

建立使用者賬戶

這一部分我們來建立使用者註冊和身份驗證系統。

應用程式users

首先使用命令python manage.py startapp users建立名為users的應用程式,現在你的目錄應該和下面一樣。

1.將應用程式users新增到settings.py

#--snip--
INSTALLED_APPS = (
    #--snip--
    'learning_logs',
    'users',
)
#--snip--

2.建立users的URL模式

from django.conf.urls import
url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^users/', include('users.urls', namespace='users')), url(r'', include('learning_logs.urls', namespace='learning_logs')), ]

新增的程式碼與任何以單詞users大頭的URL(如http://localhost:8000/users/login/)都匹配。

登入頁面

在learning_log/users/中新建一個urls.py。

from django.conf.urls import url
from django.contrib.auth.views import login

from . import views

urlpatterns = [
    url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'),
]

首先匯入預設檢視login,接著登入頁面的URL模式與URLhttp://localhost:8000/
users/login/
匹配。實參login(不是views.login)告訴django將請求傳送給檢視login。接著傳遞了一個字典指定要查詢的模板。
1.模板login.html


同樣,新建一個路徑users/templates/users/,接著在這個路徑下新建login.html。

{% 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 %}

這個模板同樣繼承了base.html。一個應用程式中的模板可繼承另一個應用程式中的模板。
表單errors屬性可以在輸入的使用者名稱-密碼錯誤時顯示錯誤訊息。
將實參action設定為登入頁面的URL,讓登入檢視處理表單。表單元素next告訴django在使用者成功登入後將其重定向到主頁。
2.連結到登入頁面
在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 %}

在django身份驗證系統中,每個模板都可以使用變數user,變數的is_authenricated屬性:如果使用者已登入,該屬性值為True,否則為Faule;變數的username屬性為使用者名稱。
3.使用登入頁面
如果你之前登入過管理員,記得先在http://127.0.0.1:8000/admin登出登入。然後重新登入我們的學習筆記網頁登入頁面http://127.0.0.1:8000/users/login/,並使用管理員的帳號密碼登入。

登出

1.登出URL

#users/urls.py
from django.conf.urls import url
from django.contrib.auth.views import login

from . import views

urlpatterns = [
    url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'),
    url(r'^logout/$', views.logout_view, name='logout'),
]

2.檢視函式logout_view()
django自帶函式模組logout(),我們只需匯入他,並呼叫他重定向到主頁。

from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.contrib.auth import logout

def logout_view(request):
    logout(request)
    return HttpResponseRedirect(reverse('learning_logs:index'))

在這裡,request物件作為實參傳遞給函式logout()
3.連結到登出檢視
在base.html中添加註銷連結。為了使得僅當用戶登入後才能看見他,我們將他放在標籤{% if user.is_authenticated %}中。

#base.html
<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 }}.
    <a href="{% url 'users:logout' %}">log out</a>
  {% else %}
    <a href="{% url 'users:login' %}">log in</a>
  {% endif %}
</p>

{% block content %}{% endblock content %}

執行伺服器可以看到

註冊頁面

1.註冊頁面的URL模式

from django.conf.urls import url
from django.contrib.auth.views import login

from . import views

urlpatterns = [
    url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'),
    url(r'^logout/$', views.logout_view, name='logout'),
    url(r'^register/$', views.register, name='register'),
]

2.檢視函式reigster()
當註冊頁面首次被請求時,檢視函式register()顯示一個空的登錄檔單,使用者提交後註冊成功並自動登入。

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import UserCreationForm

def logout_view(request):
--snip--

def register(request):
    if request.method != 'POST':
        #顯示空的登錄檔單
        form = UserCreationForm();
    else:
        #處理填寫好的表單
        form = UserCreationForm(data=request.POST)

        if form.is_valid():
            new_user = form.save()
            #讓使用者自動登入並重定向到主頁
            authenticate_user = authenticate(username=new_user.username,
                password=request.POST['password1'])
            login(request, authenticate_user)
            return HttpResponseRedirect(reverse('learning_logs:index'))

    context = {'form': form}
    return render(request, 'users/register.html', context)

函式login()和函式 authenticate()可以讓使用者註冊成功後自動登入。
在註冊的時候,如果使用者提交的登錄檔單資料有效,呼叫方法save()並返回新建立的使用者物件,儲存在new_user中。
自動登入過程中,呼叫authenticate()並把實參new_user.username和密碼(因為表單有效,兩個密碼相同,所以我們使用第一個密碼'password1')傳給它。接著我們將authenticate()返回的通過身份驗證的使用者物件儲存在authenticate_user中。最後呼叫函式login(),並把物件request和authenticate_user傳給他。最後完成自動登入。
3.註冊模板
建立一個register.html,和login.html放在一起。

{% extends "learning_logs/base.html" %}

{% block content %}

  <form method="post" action="{% url 'users:register' %}">
    {% csrf_token %}
    {{ form.as_p }}

    <button name="submit">register</button>
    <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
  </form>

{% endblock content %}

4.連結到註冊頁面

<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 }}.
    <a href="{% url 'users:logout' %}">log out</a>
  {% else %}
    <a href="{% url 'users:register' %}">register</a> - 
    <a href="{% url 'users:login' %}">log in</a>
  {% endif %}
</p>

{% block content %}{% endblock content %}

執行伺服器可以看到