《Django By Example》第四章 中文 翻譯 (個人學習,渣翻)

来源:http://www.cnblogs.com/levelksk/archive/2017/01/04/6248947.html
-Advertisement-
Play Games

(譯者註:祝大家新年快樂,這次帶來《Django By Example》第四章的翻譯,這章非常的實用,就這樣) 第四章 創建一個社交網站 在上一章中,你學習瞭如何創建站點地圖(sitemaps)和feeds,你還為你的blog應用創建了一個搜索引擎。在本章中,你將開發一個社交應用。你會為用戶創建一些 ...


(譯者註:祝大家新年快樂,這次帶來《Django By Example》第四章的翻譯,這章非常的實用,就這樣)

第四章

創建一個社交網站

在上一章中,你學習瞭如何創建站點地圖(sitemaps)和feeds,你還為你的blog應用創建了一個搜索引擎。在本章中,你將開發一個社交應用。你會為用戶創建一些功能,例如:登錄,登出,編輯,以及重置他們的密碼。你會學習如何為你的用戶創建一個定製的profile,你還會為你的站點添加社交認證。

本章將會覆蓋一下幾點:

  • 使用認證(authentication)框架
  • 創建用戶註冊視圖(views)
  • 通過一個定製的profile模型(model)擴展User模型(model)
  • 使用python-social-auth添加社交認證

讓我們開始創建我們的新項目吧。

創建一個社交網站項目

我們要創建一個社交應用允許用戶分享他們在網上找到的圖片。我們需要為這個項目構建以下元素:

  • 一個用來給用戶註冊,登錄,編輯他們的profile,以及改變或重置密碼的認證(authentication)系統
  • 一個允許用戶用來關註其他人的關註系統(這裡原文是follow,‘跟隨’,感覺用‘關註’更加適合點)
  • 為用戶從其他任何網站分享過來的圖片進行展示和打上書簽
  • 每個用戶都有一個活動流允許用戶看到他們關註的人上傳的內容

本章主要講述第一點。

開始你的社交網站項目

打開終端使用如下命令行為你的項目創建一個虛擬環境並且激活它:

mkdir evn
virtualenv evn/bookmarks
source env/bookmarks/bin/activate

shell提示將會展示你激活的虛擬環境,如下所示:

(bookmarks)laptop:~ zenx$

通過以下命令在你的虛擬環境中安裝Django:

pip install Django==1.8.6

運行以下命令來創建一個新項目:

django-admin statproject bookmarks

在創建好一個初始的項目結構以後,使用以下命令進入你的項目目錄並且創建一個新的應用命名為account:

cd bookmarks/
django-admin startapp account

請記住在你的項目中激活一個新應用需要在settings.py文件中的INSTALLED_APPS設置中添加它。將新應用的名字添加在INSTALLED_APPS列中的所有已安裝應用的最前面,如下所示:

INSTALLED_APPS = (
    'account',
    # ...
)

運行下一條命令為INSTALLED_APPS中預設包含的應用模型(models)同步到資料庫中:

python manage.py migrate

我們將要使用認證(authentication)框架來構建一個認證系統到我們的項目中。

使用Django認證(authentication)框架

Django擁有一個內置的認證(authentication)框架用來操作用戶認證(authentication),會話(sessions),許可權(permissions)以及用戶組。這個認證(authentication)系統包含了一些普通用戶的操作視圖(views),例如:登錄,登出,修改密碼以及重置密碼。

這個認證(authentication)框架位於django.contrib.auth,被其他Django的contrib包調用。請記住你使用過這個認證(authentication)框架在第一章 創建一個Blog應用中用來為你的blog應用創建了一個超級用戶來使用管理站點。

當你使用startproject命令創建一個新的Django項目,認證(authentication)框架已經在你的項目設置中預設包含。它是由django.contrib.auth應用和你的項目設置中的MIDDLEWARE_CLASSES中的兩個中間件類組成,如下:

  • AuthenticationMiddlwware:使用會話(sessions)將用戶和請求(requests)進行關聯
  • SessionMiddleware:通過請求(requests)操作當前會話(sessions)

中間件就是一個在請求和響應階段帶有全局執行方法的類。你會在本書中的很多場景中使用到中間件。你將會學習如何創建一個定製的中間件在第十三章 Going Live(譯者註:啥時候能翻譯到啊)

這個認證(authentication)系統還包含了以下模型(models):

  • User:一個用戶模型(model)包含基礎欄位;這個模型(model)的主要欄位有:username,password,email,first_name,last_name,is_active。
  • Group:一個組模型(model)用來分類用戶
  • Permission:執行特定操作的標識

這個框架還包含預設的認證(authentication)視圖(views)和表單(forms),我們之後會用到。

創建一個log-in視圖(view)

我們將要開始使用Django認證(authentication)框架來允許用戶登錄我們的網站。我們的視圖(view)需要執行以下操作來登錄用戶:

  • 1、通過提交的表單(form)獲取username和password
  • 2、通過存儲在資料庫中的數據對用戶進行認證
  • 3、檢查用戶是否可用
  • 4、登錄用戶到網站中並且開始一個認證(authentication)會話(session)

首先,我們要創建一個登錄表單(form)。在你的account應用目錄下創建一個新的forms.py文件,添加如下代碼:

from django import forms    
class LoginForm(forms.Form):        
    username = forms.CharField()        
    password = forms.CharField(widget=forms.PasswordInput)

這個表單(form)被用來通過資料庫認證用戶。請註意,我們使用PsswordInput控制項來渲染HTMLinput元素,包含type="password屬性。編輯你的account應用中的views.py文件,添加如下代碼:

from django.http import HttpResponse    
from django.shortcuts import render    
from django.contrib.auth import authenticate, login    
from .forms import LoginForm    
def user_login(request):        
    if request.method == 'POST':            
        form = LoginForm(request.POST)            
        if form.is_valid():                
            cd = form.cleaned_data                
            user = authenticate(username=cd['username'],
                                password=cd['password'])                
            if user is not None:                    
                if user.is_active:                        
                    login(request, user)                        
                    return HttpResponse('Authenticated successfully')
                else:                        
                    return HttpResponse('Disabled account')
        else:            
            return HttpResponse('Invalid login')        
    else:            
        form = LoginForm()        
    return render(request, 'account/login.html', {'form': form})

以上就是我們在視圖(view)中所作的基本登錄操作:當user_login被一個GET請求(request)調用,我們實例化一個新的登錄表單(form)通過form = LoginForm()在模板(template)中展示它。當用戶通過POST方法提交表單(form),我們執行以下操作:

  • 1、使用提交的數據實例化表單(form)通過使用form = LoginForm(request.POST)
  • 2、檢查這個表單是否有效。如果無效,我們在模板(template)中展示表單錯誤信息(舉個例如,比如用戶沒有填寫其中一個欄位就進行提交)
  • 3、如果提交的數據是有效的,我們通過資料庫對這個用戶進行認證(authentication)通過使用authenticate()方法。這個方法帶入一個username和一個password並且返回一個用戶對象如果這個用戶成功的進行了認證,或者是None。如果用戶沒有被認證通過,我們返回一個HttpResponse展示一條消息。
  • 4、如果這個用戶認證(authentication)成功,我們使用is_active屬性來檢查用戶是否可用。這是一個Django的User模型(model)屬性。如果這個用戶不可用,我們返回一個HttpResponse展示信息。
  • 5、如果用戶可用,我們登錄這個用戶到網站中。我們通過調用login()方法集合用戶到會話(session)中然後返回一條成功消息。

請註意authenticationlogin中的不同點:authenticate()檢查用戶認證信息然後返回一個用戶對象如果用戶是正確的;login()集合用戶到當前的會話(session)中。

現在,你需要為這個視圖(view)創建一個URL模式。在你的account應用目錄下創建一個新的urls.py文件,添加如下代碼:

from django.conf.urls import url    
from . import views    
urlpatterns = [        
    # post views        
    url(r'^login/$', views.user_login, name='login'),    
]

編輯位於你的bookmarks項目目錄下的urls.py文件,將account應用下的URL模式包含進去:

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

這個登錄視圖(view)現在已經可以通過URL進行訪問。現在是時候為這個視圖(view)創建一個模板。因為之前你沒有這個項目的任何模板,你可以開始創建一個主模板(template)可以被登錄模板(template)繼承使用。創建以下文件和結構在account應用目錄中:

templates/account/login.htmlbase.html

編輯base.html文件添加如下代碼:

{% load staticfiles %}    
<!DOCTYPE html>    
<html>    
    <head>      
        <title>{% block title %}{% endblock %}</title>      
        <link href="{% static "css/base.css" %}" rel="stylesheet">    
    </head>    
    <body>      
        <div id="header">        
            <span class="logo">Bookmarks</span>      
        </div>      
        <div id="content">        
            {% block content %}        
            {% endblock %}      
        </div>    
    </body>    
</html>

以上將是這個網站的基礎模板(template)。就像我們在上一章項目中做過的一樣,我們在這個住模板(template)中包含了CSS樣式。你可以在本章的示例代碼中找到這些靜態文件。複製示例代碼中的account應用下的static/目錄到你的項目中的相同位置,這樣你就可以使用這些靜態文件了。

基礎模板(template)定義了一個title和一個content區塊可以被繼承的子模板(template)填充內容。

讓我們為我們的登錄表單(form)創建模板(template)。打開account/login.html模板(template)添加如下代碼:

{% extends "base.html" %}
{% block title %}Log-in{% endblock %}
{% block content %}
    <h1>Log-in</h1>
    <p>Please, use the following form to log-in:</p>
    <form action="." method="post">
        {{ form.as_p }}
        {% csrf_token %}
        <p><input type="submit" value="Log-in"></p>
    </form>
{% endblock %}

這個模板(template)包含了視圖(view)中實例化的表單(form)。因為我們的表單(form)將會通過POST方式進行提交,所以我們包含了{% csrf_token %}模板(template)標簽(tag)用來通過CSRF保護。你已經學習過CSRF保護在第二章 使用高級特性擴展你的博客應用

目前還沒有用戶在你的資料庫中。你首先需要創建一個超級用戶用來登錄管理站點來管理其他的用戶。打開命令行執行python manage.py createsuperuser。填寫username,e-mail以及password。之後通過命令python manage.py runserver運行開發環境,然後在你的瀏覽器中打開 http://127.0.0.1:8000/admin/ 。使用你剛纔創建的username和passowrd來進入管理站點。你會看到Django管理站點包含Django認證(authentication)框架中的UserGroup模型(models)。如下所示:

django-4-1

使用管理站點創建一個新的用戶然後打開 http://127.0.0.1:8000/account/login/ 。你會看到被渲染過的模板(template),包含一個登錄表單(form):

django-4-2

現在,只填寫一個欄位保持另外一個欄位為空進行表單(from)提交。在這例子中,你會看到這個表單(form)是無效的並且顯示了一個錯誤信息:

django-4-3

如果你輸入了一個不存在的用戶或者一個錯誤的密碼,你會得到一個Invalid login信息。

如果你輸入了有效的認證信息,你會得到一個Authenticated successfully消息:

django-4-4

使用Django認證(authentication)視圖(views)

Django包含了一些表單(forms)和視圖(views)在認證(authentication)框架中讓你可以立刻(straightaway)使用。你之前創建的登錄視圖(view)是一個非常的練慣用來理解Django中的用戶認證(authentication)過程。無論如何,你可以使用預設的Django認證(authentication)視圖(views)在大部分的例子中。

Django提供以下視圖(views)來處理認證(authentication):

  • login:操作表單(form)中的登錄然後登錄一個用戶
  • logout:登出一個用戶
  • logout_then_login:登出一個用戶然後重定向這個用戶到登錄頁面

Django提供以下視圖(views)來操作密碼修改:

  • password_change:操作一個表單(form)來修改用戶密碼
  • password_change_done:當用戶成功修改他的密碼後提供一個成功提示頁面

Django還包含了以下視圖(views)允許用戶重置他們的密碼:

  • password_reset:允許用戶重置他的密碼。它會生成一條帶有一個token的一次性使用鏈接然後發送到用戶的郵箱中。
  • password_reset_done:告知用戶已經發送了一封可以用來重置密碼的郵件到他的郵箱中。
  • password_reset_complete:當用戶重置完成他的密碼後提供一個成功提示頁面。

以上的視圖(views)可以幫你節省很多時間當你創建一個帶有用戶賬號的網站。這些視圖(views)使用的預設值你可以進行覆蓋,例如需要渲染的模板位置或者視圖(view)需要使用到的表單(form)。

你可以通過訪問 https://docs.
djangoproject.com/en/1.8/topics/auth/default/#module-django.contrib.auth.views 獲取更多內置的認證(authentication)視圖(views)信息。

登錄和登出視圖(views)

編輯你的account應用下的urls.py文件,如下所示:

from django.conf.urls import url
from . import views
urlpatterns = [
    # previous login view
    # url(r'^login/$', views.user_login, name='login'),
    # login / logout urls
    url(r'^login/$',
        'django.contrib.auth.views.login',
        name='login'),
    url(r'^logout/$',
        'django.contrib.auth.views.logout',
        name='logout'),
    url(r'^logout-then-login/$',
        'django.contrib.auth.views.logout_then_login',
        name='logout_then_login'),
]

我們將之前創建的user_login視圖(view)URL模式進行註釋,然後使用Django認證(authentication)框架提供的login視圖(view)。

在你的account應用中的template目錄下創建一個新的目錄命名為registration。這個路徑是Django認證(authentication)視圖(view)期望你的認證(authentication)模塊(template)預設的存放路徑。在這個新目錄中創建一個新的文件,命名為login.html,然後添加如下代碼:

{% extends "base.html" %}
{% block title %}Log-in{% endblock %}
{% block content %}
  <h1>Log-in</h1>
  {% if form.errors %}
    <p>
      Your username and password didn't match.
      Please try again.
    </p>
  {% else %}
    <p>Please, use the following form to log-in:</p>
  {% endif %}
  <div class="login-form">
    <form action="{% url 'login' %}" method="post">
      {{ form.as_p }}
      {% csrf_token %}
      <input type="hidden" name="next" value="{{ next }}" />
      <p><input type="submit" value="Log-in"></p>
    </form>
  </div>
 {% endblock %}

這個登錄模板(template)和我們之前創建的基本類似。Django預設使用位於django.contrib.auth.forms中的AuthenticationForm。這個表單(form)會嘗試對用戶進行認證如果登錄不成功就會拋出一個驗證錯誤。在這個例子中,我們可以在模板(template)中使用{% if form.errors %}來找到錯誤如果用戶提供了錯誤的認證信息。請註意,我們添加了一個隱藏的HTML<input>元素來提交叫做next的變數值。這個變數是登錄視圖(view)的首個設置當你在請求(request)中傳遞一個next參數(舉個例子:http://127.0.0.1:8000/account/login/?next=/account/)。

next參數必須是一個URL。當這個參數被給予的時候,Django登錄視圖(view)將會在用戶登錄完成後重定向到給予的URL。

現在,在registrtion模板(template)目錄下創建一個logged_out.html模板(template)添加如下代碼:

{% extends "base.html" %}
{% block title %}Logged out{% endblock %}
{% block content %}
  <h1>Logged out</h1>
  <p>You have been successfully logged out. You can <a href="{% url "login" %}">log-in again</a>.</p>
{% endblock %}

這個模板(template)Django會在用戶登出的時候進行展示。

在添加了URL模式以及登錄和登出視圖(view)的模板之後,你的網站已經準備好讓用戶使用Django認證(authentication)視圖進行登錄。

請註意,在我們的地址配置中包含的logtou_then_login視圖(view)不需要任何模板(template),因為它執行了一個重定向到登錄視圖(view)。

現在,我們要創建一個新的視圖(view)來顯示一個dashboard給用戶當他或她登錄他們的賬號。打開你的account應用中的views.py文件,添加以下代碼:

from django.contrib.auth.decorators import login_required
@login_required
def dashboard(request):
    return render(request,
                 'account/dashboard.html',
                 {'section': 'dashboard'})

我們使用認證(authentication)框架的login_required裝飾器(decorator)裝飾我們的視圖(view)。login_required裝飾器(decorator)會檢查當前用戶是否通過認證,如果用戶通過認證,它會執行裝飾的視圖(view),如果用戶沒有通過認證,它會把用戶重定向到帶有一個名為next的GET參數的登錄URL,該GET參數保存的變數為用戶當前嘗試訪問的頁面URL。通過這些動作,登錄視圖(view)會將登錄成功的用戶重定向到用戶登錄之前嘗試訪問過的URL。請記住我們在登錄模板(template)中的登錄表單(form)中添加的隱藏<input>就是為了這個目的。

我們還定義了一個section變數。我們會使用該變數來跟蹤用戶在站點中正在查看的頁面。多個視圖(views)可能會對應相同的section。這是一個簡單的方法用來定義每個視圖(view)對應的section。

現在,你需要創建一個給dashboard視圖(view)使用的模板(template)。在templates/account/目錄下創建一個新文件命名為dashboard.html。添加如下代碼:

{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
  <h1>Dashboard</h1>
  <p>Welcome to your dashboard.</p>
{% endblock %}

之後,為這個視圖(view)在account應用中的urls.py文件中添加如下URL模式:

urlpatterns = [
    # ...
    url(r'^$', views.dashboard, name='dashboard'),
]

編輯你的項目的settings.py文件,添加如下代碼:

from django.core.urlresolvers import reverse_lazy
LOGIN_REDIRECT_URL = reverse_lazy('dashboard')
LOGIN_URL = reverse_lazy('login')
LOGOUT_URL = reverse_lazy('logout')

這些設置的意義:

  • LOGIN_REDIRECT_URL:告訴Django用戶登錄成功後如果contrib.auth.views.login視圖(view)沒有獲取到next參數將會預設重定向到哪個URL。
  • LOGIN_URL:重定向用戶登錄的URL(例如:使用login_required裝飾器(decorator))。
  • LOGOUT_URL:重定向用戶登出的URL。

我們使用reverse_laze()來動態構建URL通過它們的名字。reverse_laze()方法reverses URLs就像reverse()所做的一樣,但是你可以使用它當你需要reverse URLs在你項目的URL配置讀取之前。

讓我們總結下目前為止我們都做了哪些工作:

  • 你在項目中添加了Django內置的認證(authentication)登錄和登出視圖(views)。
  • 你為每一個視圖(view)創建了定製的模板(templates),並且定義了一個簡單的視圖(view)讓用戶登錄後進行重定向。
  • 最後,你配置了你的Django設置使用預設的URLs。

現在,我們要給我們的主模板(template)添加登錄和登出鏈接將所有的一切都連接起來。

為了做到這點,我們必須確定無論用戶是已登錄狀態還是沒有登錄的時候,都會顯示適當的鏈接。通過認證(authentication)中間件當前的用戶被集合在HTTP請求(request)對象中。你可以訪問用戶信息通過使用request.user。你會防線一個用戶對象在請求(request)中,即使這個用戶並沒有認證通過。一個非認證的用戶在請求(request)被設置成一個AnonymousUser的實例。一個最好的方法來檢查當前的用戶是否通過認證是通過調用request.user.is_authenticated()

編輯你的base.html文件修改ID為header<div>元素,如下所示:

<div id="header">
<span class="logo">Bookmarks</span>
{% if request.user.is_authenticated %}
     <ul class="menu">
      <li {% if section == "dashboard" %}class="selected"{% endif %}>
        <a href="{% url "dashboard" %}">My dashboard</a>
      </li>
      <li {% if section == "images" %}class="selected"{% endif %}>
        <a href="#">Images</a>
      </li>
      <li {% if section == "people" %}class="selected"{% endif %}>
        <a href="#">People</a>
       </li>
      </ul>
     {% endif %}
     <span class="user">
       {% if request.user.is_authenticated %}
         Hello {{ request.user.first_name }},
         <a href="{% url "logout" %}">Logout</a>
       {% else %}
         <a href="{% url "login" %}">Log-in</a>
       {% endif %}
    </span>
</div>

就像你所看到的,我們只給通過認證(authentication)的用戶顯示站點菜單。我們還檢查當前的section來給對應的<li>組件添加一個selected的class屬性來使當前section在菜單中進行高亮顯示通過使用CSS。我們還顯示用戶的第一個名字和一個登出的鏈接如果用戶已經通過認證(authentication),否則,就是一個登出鏈接。

現在,在瀏覽器中打開 http://127.0.0.1:8000/account/login/ 。你會看到登錄頁面。輸入可用的用戶名和密碼然後點擊Log-in按鈕。你會看到如下圖所示:

django-4-5

你能看到My Dashboard section 通過CSS的作用高亮顯示因為它擁有一個selected class。因為當前用戶已經通過了認證(authentication)所有用戶的第一個名字在右上角進行了顯示。點擊Logout鏈接。你會看到如下圖所示:

django-4-6

在這個頁面中,你能看到用戶已經登出,然後,你無法看到當前網站的任何菜單。在右上角現在顯示的是Log-in鏈接。

如果你在你的登出頁面中看到了Django管理站點的登出頁面,檢查項目settings.py中的INSTALLED_APPS,確保django.contrib.adminaccount應用的後面。每個模板(template)被定位在同樣的相對路徑時,Django模板(template)讀取器將會使用它找到的第一個應用中的模板(templates)。

修改密碼視圖(views)

我們還需要我們的用戶在登錄成功後可以進行修改密碼。我們要集成Django認證(authentication)視圖(views)來修改密碼。打開account應用中的urls.py文件,添加如下URL模式:

# change password urls
url(r'^password-change/$',
   'django.contrib.auth.views.password_change',
   name='password_change'),
url(r'^password-change/done/$',
   'django.contrib.auth.views.password_change_done',
   name='password_change_done'),

password_change視圖(view)將會操作表單(form)進行修改密碼,password_change_done將會顯示一條成功信息當用戶成功的修改他的密碼。讓我們為每個視圖(view)創建一個模板(template)。

在你的account應用templates/registration/目錄下添加一個新的文件命名為password_form.html,在文件中添加如下代碼:

{% extends "base.html" %}
{% block title %}Change you password{% endblock %}
{% block content %}
  <h1>Change you password</h1>
  <p>Use the form below to change your password.</p>
  <form action="." method="post">
    {{ form.as_p }}
    <p><input type="submit" value="Change"></p>
    {% csrf_token %}
  </form>
{% endblock %}

這個模板(template)包含了修改密碼的表單(form)。現在,在相同的目錄下創建另一個文件,命名為password_change_done.html,為它添加如下代碼:

{% extends "base.html" %}
{% block title %}Password changed{% endblock %}
{% block content %}
  <h1>Password changed</h1>
  <p>Your password has been successfully changed.</p>
 {% endblock %}
 

這個模板(template)只包含顯示一條成功的信息 當用戶成功的修改他們的密碼。

在瀏覽器中打開 http://127.0.0.1:8000/account/password-change/ 。如果你的用戶沒有登錄,瀏覽器會重定向你到登錄頁面。在你成功認證(authentication)登錄後,你會看到如下圖所示的修改密碼頁面:

django-4-7

在表單(form)中填寫你的舊密碼和新密碼,然後點擊Change按鈕。你會看到如下所示的成功頁面:

django-4-8

登出再使用新的密碼進行登錄來驗證每件事是否如預期一樣工作。

重置密碼視圖(views)

account應用urls.py文件中為密碼重置添加如下URL模式:

# restore password urls
 url(r'^password-reset/$',
    'django.contrib.auth.views.password_reset',
    name='password_reset'),
 url(r'^password-reset/done/$',
     'django.contrib.auth.views.password_reset_done',
     name='password_reset_done'),
  url(r'^password-reset/confirm/(?P<uidb64>[-\w]+)/(?P<token>[-\w]+)/$',
       'django.contrib.auth.views.password_reset_confirm',
     name='password_reset_confirm'),
 url(r'^password-reset/complete/$',
     'django.contrib.auth.views.password_reset_complete',
      name='password_reset_complete'),

在你的account應用templates/registration/目錄下添加一個新的文件命名為password_reset_form.html,為它添加如下代碼:

{% extends "base.html" %}
{% block title %}Reset your password{% endblock %}
{% block content %}
  <h1>Forgotten your password?</h1>
  <p>Enter your e-mail address to obtain a new password.</p>
  <form action="." method="post">
    {{ form.as_p }}
    <p><input type="submit" value="Send e-mail"></p>
    {% csrf_token %}
  </form>
{% endblock %}

現在,在相同的目錄下添加另一個文件命名為password_reset_email.html,為它添加如下代碼:

Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol }}://{{ domain }}{% url "password_reset_confirm" uidb64=uid token=token %}
Your username, in case you've forgotten: {{ user.get_username }}

這個模板(template)會被用來渲染髮送給用戶的重置密碼郵件。

在相同目錄下添加另一個文件命名為*password_reset_done.html,為它添加如下代碼:

{% extends "base.html" %}
{% block title %}Reset your password{% endblock %}
{% block content %}
  <h1>Reset your password</h1>
  <p>We've emailed you instructions for setting your password.</p>
  <p>If you don't receive an email, please make sure you've entered the address you registered with.</p>
{% endblock %}

再創建另一個模板(template)命名為passowrd_reset_confirm.html,為它添加如下代碼:

{% extends "base.html" %}
{% block title %}Reset your password{% endblock %}
{% block content %}
  <h1>Reset your password</h1>
  {% if validlink %}
    <p>Please enter your new password twice:</p>
    <form action="." method="post">
      {{ form.as_p }}
      {% csrf_token %}
      <p><input type="submit" value="Change my password" /></p>
    </form>
  {% else %}
    <p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p>
  {% endif %}
{% endblock %}

在以上模板中,如果重置鏈接是有效的我們將會進行檢查。Django重置密碼視圖(view)會設置這個變數然後將它帶入這個模板(template)的上下文環境中。如果重置鏈接有效,我們展示用戶密碼重置表單(form)。

創建另一個模板(template)命名為password_reset_complete.html,為它添加如下代碼:

{% extends "base.html" %}
{% block title %}Password reset{% endblock %}
{% block content %}
  <h1>Password set</h1>
  <p>Your password has been set. You can <a href="{% url "login" %}">log in now</a></p>
{% endblock %}

最後,編輯account應用中的/registration/login.html模板(template),添加如下代碼在<form>元素之後:

<p><a href="{% url "password_reset" %}">Forgotten your password?</a></p>

現在,在瀏覽器中打開 http://127.0.0.1:8000/account/login/ 然後點擊Forgotten your password?鏈接。你會看到如下圖所示頁面:

django-4-9

在這部分,你需要在你項目中的settings.py中添加一個SMTP配置,這樣Django才能發送e-mails。我們已經學習過如何添加e-mail配置在第二章 使用高級特性來優化你的blog。當然,在開發期間,我們可以配置Django在標準輸出中輸出e-mail內容來代替通過SMTP服務發送郵件。Django提供一個e-mail後端來輸出e-mail內容到控制器中。編輯項目中settings.py文件,添加如下代碼:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

EMAIL_BACKEND設置這個類用來發送e-mails。

回到你的瀏覽器中,填寫一個存在用戶的e-mail地址,然後點擊Send e-mail按鈕。你會看到如下圖所示頁面:

django-4-10

當你運行開發服務的時候看眼控制台輸出。你會看到如下所示生成的e-mail:

IME-Version: 1.0
 Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Subject: Password reset on 127.0.0.1:8000
From: webmaster@localhost
To: [email protected]
Date: Thu, 24 Sep 2015 14:35:08 -0000
Message-ID: <[email protected]>
Someone asked for password reset for email [email protected]. Follow the link below:
http://127.0.0.1:8000/account/password-reset/confirm/MQ/45f-9c3f30caafd523055fcc/
Your username, in case you've forgotten: zenx

這封e-mail被我們之前創建的password_reset_email.html模板給渲染。這個給你重置密碼的URL帶有一個Django動態生成的token。在瀏覽器中打開這個鏈接,你會看到如下所示頁面:

django-4-11

這個頁面用來設置新密碼對應password_reset_confirm.html模板(template)。填寫新的密碼然後點擊Change my password button。Django會創建一個新的加密後密碼保存進資料庫,你會看到如下圖所示頁面:

django-4-12

現在你可以使用你的新密碼登錄你的賬號。每個用來設置新密碼的token只能使用一次。如果你再次打開你之前獲取的鏈接,你會得到一條信息告訴你這個token已經無效了。

你在項目中集成了Django認證(authentication)框架的視圖(views)。這些視圖(views)對大部分的例子都適合。當然,你能創建你的自己視圖如果你需要一種不同的行為。

用戶註冊和用戶profiles

現有的用戶已經可以登錄,登出,修改他們的密碼,以及當他們忘記密碼的時候重置他們的密碼。現在,我們需要構建一個視圖(view)允許訪問者創建他們的賬號。

用戶註冊

讓我們創建一個簡單的視圖(view)允許用戶在我們的網站中進行註冊。首先,我們需要創建一個表單(form)讓用戶填寫用戶名,他們的真實姓名以及密碼。編輯account應用新目錄下的forms.py文件添加如下代碼:

from django.contrib.auth.models import User
class UserRegistrationForm(forms.ModelForm):
    password = forms.CharField(label='Password',
                               widget=forms.PasswordInput)
    password2 = forms.CharField(label='Repeat password',
                                widget=forms.PasswordInput)
    class Meta:
        model = User
        fields = ('username', 'first_name', 'email')
    def clean_password2(self):
        cd = self.cleaned_data
        if cd['password'] != cd['password2']:
            raise forms.ValidationError('Passwords don\'t match.')
        return cd['password2']
        

我們為User模型(model)創建了一個model表單(form)。在我們的表單(form)中我們只包含了模型(model)中的username,first_name,email欄位。這些欄位會在它們對應的模型(model)欄位上進行驗證。例如:如果用戶選擇了一個已經存在的用戶名,將會得到一個驗證錯誤。我們還添加了兩個額外的欄位passwordpassword2給用戶用來填寫他們的新密碼和確定密碼。我們定義了一個clean_password2()方法去檢查第二次輸入的密碼是否和第一次輸入的保持一致,如果不一致這個表單將會是無效的。這個檢查會被執行當我們驗證這個表單(form)通過調用它的is_valid()方法。你可以提供一個clean_<fieldname>()方法給任何一個你的表單(form)欄位用來清理值或者拋出表單(from)指定的欄位的驗證錯誤。表單(forms)還包含了一個clean()方法用來驗證表單(form)的所有內容,這是非常有用的用來驗證需要依賴其他欄位的欄位。

Django還提供一個UserCreationForm表單(form)給你使用,它位於django.contrib.auth.forms非常類似與我們剛纔創建的表單(form)。

編輯account應用中的views.py文件,添加如下代碼:

from .forms import LoginForm, UserRegistrationForm
def register(request):
    if request.method == 'POST':
        user_form = UserRegistrationForm(request.POST)
        if user_form.is_valid():
            # Create a new user object but avoid saving it yet
            new_user = user_form.save(commit=False)
            # Set the chosen password
            new_user.set_password(
                user_form.cleaned_data['password'])
            # Save the User object
            new_user.save()
            return render(request,
                         'account/register_done.html',
                         {'new_user': new_user})
    else:
        user_form = UserRegistrationForm()
    return render(request,
                 'account/register.html',
                 {'user_form': user_form})

這個創建用戶賬號的視圖(view)非常簡單。為了保護用戶的隱私,我們使用User模型(model)的set_password()方法將用戶的原密碼進行加密後再進行保存操作。

現在,編輯account應用中的urls.py文件,添加如下URL模式:

url(r'^register/$', views.register, name='register'),

最後,創建一個新的模板(template)在account/模板(template)目錄下,命名為register.html,為它添加如下代碼:

{% extends "base.html" %}
{% block title %}Create an account{% endblock %}
{% block content %}
  <h1>Create an account</h1>
  <p>Please, sign up using the following form:</p>
  <form action="." method="post">
    {{ user_form.as_p }}
    {% csrf_token %}
    <p><input type="submit" value="Create my account"></p>
  </form>
{% endblock %}

在相同的目錄中添加一個模板(template)文件命名為register_done.html,為它添加如下代碼:

{% extends "base.html" %}
{% block title %}Welcome{% endblock %}
{% block content %}
  <h1>Welcome {{ new_user.first_name }}!</h1>
  <p>Your account has been successfully created. Now you can <a href="{% url "login" %}">log in</a>.</p>
{% endblock %}

現在,在瀏覽器中打開 http://127.0.0.1:8000/account/register/ 。你會看到你創建的註冊頁面:

django-4-13

填寫用戶信息然後點擊Create my account按鈕。如果所有的欄位都驗證都過,這個用戶將會被創建然後會得到一條成功信息,如下所示:

django-4-14

點擊log-in鏈接輸入你的用戶名和密碼來驗證賬號是否成功創建。

現在,你還可以添加一個註冊鏈接在你的登錄模板(template)中。編輯registration/login.html模板(template)然後替換以下內容:

<p>Please, use the following form to log-in:</p>

為:

<p>Please, use the following form to log-in. If you don't have an account <a href="{% url "register" %}">register here</a></p>

如此,我們就可以從登錄頁面進入註冊頁面。

擴展User模型(model)

當你需要處理用戶賬號,你會發現Django認證(authentication)框架的User模型(model)只適應一般的案例。無論如何,User模型(model)只有一些最基本的欄位。你可能希望擴展User模型包含額外的數據。最好的辦法就是創建一個profile模型(model)包含所有額外的欄位並且和Django的User模型(model)做一對一的關聯。

編輯account應用中的model.py文件,添加如下代碼:

from django.db import models
from django.conf import settings
class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL)
    date_of_birth = models.DateField(blank=True, null=True)
    photo = models.ImageField(upload_to='users/%Y/%m/%d', blank=True)
def __str__(self):
    return 'Profile for user {}'.format(self.user.username)

為了保持你的代碼通用化,使用get_user_model()方法來取回用戶模型(model),當定義了模型(model)和用戶模型的關係使用AUTH_USER_MODEL設置來引用它,替代直接引用auth的User模型(model)。

user一對一欄位允許我們關聯用戶和profiles。photo欄位是一個ImageField欄位。你需要安裝一個Python包來管理圖片,使用PIL(Python Imaging Library)或者Pillow(PIL的分叉),在shell中運行一下命令來安裝Pillow

pip install Pillow==2.9.0

為了Django能在開發服務中管理用戶上傳的多媒體文件,在項目setting.py文件中添加如下設置:

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

MEDIA_URL 是管理用戶上傳的多媒體文件的主URL,MEDIA_ROOT是這些文件在本地保存的路徑。我們動態的構建這些路徑相對我們的項目路徑來確保我們的代碼更通用化。

現在,編輯bookmarks項目中的主urls.py文件,修改代碼如下所示:

from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^account/', include('account.urls')),
]
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,
                        document_root=settings.MEDIA_ROOT)

在這種方法中,Django開發伺服器將會在開發時改變對多媒體文件的服務。

static()幫助函數最適合在開發環境中使用而不是在生產環境使用。絕對不要在生產環境中使用Django來服務你的靜態文件。

打開終端運行以下命令來為新的模型(model)創建資料庫遷移:

python manage.py makemigrations

你會獲得以下輸出:

Migrations for 'account':
    0001_initial.py:
        - Create model Profile
        

接著,同步資料庫通過以下命令:

python manage.py migrate

你會看到包含以下內容的輸出:

Applying account.0001_initial... OK

編輯account應用中的admin.py文件,在管理站點註冊Profiel模型(model),如下所示:

from django.contrib import admin
from .models import Profile
class ProfileAdmin(admin.ModelAdmin):
    list_display = ['user', 'date_of_birth', 'photo']
admin.site.register(Profile, ProfileAdmin)

使用`python manage.py runnserver命令重新運行開發服務。現在,你可以看到Profile*模型已經存在你項目中的管理站點中,如下所示:

django-4-15

現在,我們要讓用戶可以在網站編輯它們的profile。添加如下的模型(model)表單(forms)到account應用中的forms.py文件:

from .models import Profile
class UserEditForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')
class ProfileEditForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ('date_of_birth', 'photo')

這兩個表單(forms)的功能:

  • UserEditForm:允許用戶編輯它們的first name,last name, e-mail,這些儲存在User模型(model)中的內置欄位。
  • ProfileEditForm:允許用戶編輯我們存儲在定製的Profile模型(model)中的額外數據。用戶可以編輯它們的生日數據以及為他們的profile上傳一張圖片。

編輯account應用中的view.py文件,導入Profile模型(model),如下所示:

from .models import Profile

然後添加如下內容到register視圖(view)中的new_user.save()下方:

# Create the user profile
profile = Profile.objects.create(user=new_user)

當用戶在我們的站點中註冊,我們會創建一個對應的空的profile給他們。你需要為之前創建的用戶們一個個手動創建一個Profile對象在管理站點中。

現在,我們要讓用於能夠編輯他們的pfofile。添加如下代碼到相同文件中:

from .forms import LoginForm, UserRegistrationForm, \
UserEditForm, ProfileEditForm
@login_required
def edit(request):
    if request.method == 'POST':
        user_form = UserEditForm(instance=request.user,
                                data=request.POST)
        profile_form = ProfileEditForm(instance=request.user.profile,
                                        data=request.POST,
                                        files=request.FILES)
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
    else:
        user_form = UserEditForm(instance=request.user)
        profile_form = ProfileEditForm(instance=request.user.profile)
    return render(request,
                 'account/edit.html',
                 {'user_form': user_form,
                 'profile_form': profile_form})

我們使用login_required裝飾器decorator是因為用戶編輯他們的profile必須是認證通過的狀態。在這個例子中,我們使用兩個模型(model)表單(forms):UserEditForm用來存儲數據到內置的User模型(model)中,ProfileEditForm用來存儲額外的profile數據。為了驗證提交的數據,我們檢查每個表單(forms)通過is_valid()方法是否都返回True。在這個例子中,我們保存兩個表單(form)來更新資料庫中對應的對象。

account應用中的urls.py文件中添加如下URL模式:

url(r'^edit/$', views.edit, name='edit'),

最後,在templates/account/中創建一個新的模板(template)命名為edit.html,為它添加如下內容:

{% extends "base.html" %}
{% block title %}Edit your account{% endblock %}
{% block content %}
    <h1>Edit your account</h1>
    <p>You can edit your account using the following form:</p>
    <form action="." method="post" enctype="multipart/form-data">
        {{ user_form.as_p }}
        {{ profile_form.as_p }}
        {% csrf_token %}
    <p><input type="submit" value="Save changes"></p>
    </form>
{% endblock %}

我們在表單(form)中包含enctype="multipart/form-data"用來支持文件上傳。我們使用一個HTML表單來提交兩個user_formprofile_form表單(forms)。

註冊一個新用戶然後打開 http://127.0.0.1:8000/account/edit/。你會看到如下所示頁面

django-4-16

現在,你可以編輯dashboard頁麵包含編輯profile的頁面鏈接和修改密碼的頁面鏈接。打開account/dashboard.html模板(model)替換如下代碼:

<p>Welcome to your dashboard.</p>

為:

<p>Welcome to your dashboard. You can <a href="{% url "edit" %}">edit your profile</a> or <a href="{% url "password_change" %}">change your password</a>.</p>

用戶現在可以從他們的dashboard訪問編輯他們的profile的表單。

使用一個定製User模型(model)

Django還提供一個方法可以使用你自己定製的模型(model)來替代整個User模型(model)。你自己的用戶類需要繼承Django的AbstractUser類,這個類提供了一個抽象的模型(model)用來完整執行預設用戶。你可訪問 https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#substituting-a-custom-user-model來獲得這個方法的更多信息

使用一個定製的用戶模型(model)將會帶給你很多的靈活性,但是它也可能給一些需要與User模型(model)交互的即插即用的應用集成帶來一定的困難。

使用messages框架

當處理用戶的操作時,你可能想要通知你的用戶關於他們操作的結果。Django有一個內置的messages框架允許你給你的用戶顯示一次性的提示。messages框架位於django.contrib.messages,當你使用python manage.py startproject命令創建一個新項目的時候,messages框架就被預設包含在settings.py文件中的INSTALLED_APPS中。你會註意到你的設置文件包含了一個名為django.contrib.messages.middleware.MessageMiddleware的中間件在MIDDLEWARE_CLASSES設置中。messages框架提供了一個簡單的方法添加消息給用戶。消息被存儲在資料庫中並且會在用戶的下一次請求中展示。你可以在你的視圖(views)中導入messages模塊使用消息messages框架,用簡單的快捷方式添加新的messages,如下所示:

from django.contrib import messages
messages.error(request, 'Something went wrong')

你可以使用add_message()方法創建新的messages或用下方任意一個快捷方法:

  • success():當操作成功後顯示成功的messages
  • info():展示messages
  • warning():某些還沒有達到失敗的程度但已經包含有失敗的風險,警報用
  • error():操作沒有成功或者某些事情失敗
  • debug():在生產環境中這種messages會移除或者忽略

讓我們顯示messages給用戶。因為messages框架是被項目全局應用,我們可以在主模板(template)誒用戶展示messages。打開base.html模板(template)在id為header<div>和id為content<div>之間添加如下內容:

{% if messages %}
 <ul class="messages">
   {% for message in messages %}
     <li class="{{ message.tags }}">
    {{ message|safe }}
        <a href="#" class="close"> </a>
     </li>
   {% endfor %}
 </ul>
{% endif %}

messages框架帶有一個上下文環境(context)處理器用來添加一個messages變數給請求的上下文環境(context)。所以你可以在模板(template)中使用這個變數用來給用戶顯示當前的messages。

現在,讓我們修改edit視圖(view)來使用messages框架。編輯應用中的views.py文件,使edit視圖(view)如下所示:

from django.contrib import messages
@login_required
def edit(request):
    if request.method == 'POST':
    # ...
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            messages.success(request, 'Profile updated '\
                                     'successfully')
        else:
            messages.error(request, 'Error updating your profile')
    else:
        user_form = UserEditForm(instance=request.user)
        # ...    
        

當用戶成功的更新他們的profile時我們就添加了一條成功的message,但如果某個表單(form)無效,我們就添加一個錯誤message。

在瀏覽器中打開 http://127.0.0.1:8000/account/edit/ 編輯你的profile。當profile更新成功,你會看到如下message:

django-4-17

當表單(form)是無效的,你會看到如下message:

django-4-18

創建一個定製的認證(authentication)後臺

Django允許你通過不同的來源進行認證(authentication)。AUTHENTICATION_BACKENDS設置包含了所有的認證(authentication)後臺給你的項目。預設的,這個設置如下所示:

('django.contrib.auth.backends.ModelBackend',)

這個預設的ModelBackend認證(authentication)用戶通過資料庫使用的是django.contrib.auth中的User模型(model)。這適用於你的大部分項目。當然,你還可以創建定製的後臺用來認證你的用戶通過其他的來源例如一個LDAP目錄或者其他任何系統。

你可以通過訪問 https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#other-authentication-sources 獲得更多的信息關於自定義的認證(authentication)。

當你使用django.contrib.authauthenticate()函數,Django會嘗試認證(authentication)用戶一個接一個通過每一個定義在AUTHENTICATION_BACKENDS中的後臺,直到其中有一個後臺成功的認證該用戶才會停止進行認證。只有所有的後臺都無法進行用戶認證(authentication),他或她才不會在你的站點中認證(authentication)通過。

Django提供了一個簡單的方法來定義你自己的認證(authentication)後臺。一個認證(authentication)後臺就是一個類提供瞭如下兩種方法:

  • authenticate():將用戶信息當成參數,如果用戶成功的認證(authentication)就需要返回True,反之,需要返回False
  • get_user():將用戶的ID當成參數然後需要返回一個用戶對象。

創建一個定製認證(authentication)後臺非常容易就是編寫一個Python類實現上面兩個方法。我們要創建一個認證(authentication)後臺讓用戶在我們的站點中使用他們e-mail替代他們的用戶名來進行認證(authentication)。

在你的account應用中創建一個新的文件命名為authentication.py,為它添加如下代碼:

from django.contrib.auth.models import User
class EmailAuthBackend(object):
    """
    Authenticate using e-mail account.
    """
    def authenticate(self, username=None, password=None):
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user
            return None
        except User.DoesNotExist:
            return None
    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
return None

這是一個簡單的認證(authentication)後臺。authenticate()方法接收了usernamepassword兩個可選參數。我們可以使用不同的參數,但是我們需要使用usernamepassword來確保我們的後臺可以立馬在認證(authentication)框架視圖(views)中工作。以上代碼完成了以下工作內容:

  • authenticate():我們嘗試獲取一個用戶通過給予的e-mail地址和使用User模型(model)中內置的check_password()方法來檢查密碼。這個方法會對給予密碼進行哈希化來和資料庫中存儲的加密密碼進行匹配。
  • get_user():我們獲取一個用戶通過user_id參數。Django使用這個後臺來認證用戶之後取回User對象放置到持續的用戶會話中。

編輯項目中的settings.py文件添加如下設置:

AUTHENTICATION_BACKENDS = (
   'django.contrib.auth.backends.ModelBackend',
   'account.authentication.EmailAuthBackend',
)

我們保留預設的ModelBacked用來保證用戶仍然可以通過用戶名和密碼進行認證,接著我們包含進了我們自己的email-based認證(authentication)後臺。現在,在瀏覽器中打開 http://127.0.0.1:8000/account/login/ 。請記住,Django會對每個後臺都嘗試進行用戶認證(authentication),所以你可以使用用戶名或者使用email來進行無縫登錄。

AUTHENTICATION_BACKENDS設置中的後臺排列順序。如果相同的認證信息在多個後臺都是有效的,Django會停止在第一個成功認證(authentication)通過的後臺,不再繼續進行認證(authentication)。

為你的站點添加社交認證(authentication)

你可以希望給你的站點添加一些社交認證(authentication)服務,例如 FacebookTwitter或者Google(國內就算了- -|||)。Python-social-auth是一個Python模塊提供了簡化的處理為你的網站添加社交認證(authentication)。通過使用這個模塊,你可以讓你的用戶使用他們的其他服務的賬號來登錄你的網站。你可以訪問 https://github.com/omab/python-social-auth 得到這個模塊的代碼。

這個模塊自帶很多認證(authentication)後臺給不同的Python框架,其中就包含Django。

使用pip來安裝這個包,打開終端運行如下命令:

pip install python-social-auth==0.2.12

安裝成功後,我們需要在項目settings.py文件中的INSTALLED_APPS設置中添加social.apps.django_app.default

INSTALLED_APPS = (
    #...
    'social.apps.django_app.default',
)

這個default應用會在Django項目中添加python-social-auth。現在,運行以下命令來同步python-social-auth模型(model)到你的資料庫中:

python manage.py migrate

你會看到如下default應用的數據遷移輸出:

Applying default.0001_initial... OK
Applying default.0002_add_related_name... OK
Applying default.0003_alter_email_max_length... OK

python-social-auth包含了很多服務的後臺。你可以訪問 https://python-social-auth.readthedocs.org/en/latest/backends/index.html#supported-backends 看到所有的後臺支持。

我們要包含的認證(authentication)後臺包括FacebookTwitterGoogle

你需要在你的項目中添加社交登錄URL模型。打開bookmarks項目中的主urls.py文件,添加如下URL模型:

url('social-auth/',
    include('social.apps.django_app.urls', namespace='social')),

為了確保社交認證(authentication)可以工作,你還需要配置一個hostname,因為有些服務不允許重定向到127.0.0.1localhost。為瞭解決這個問題,在Linux或者Mac OSX下,編輯你的/etc/hosts文件添加如下內容:

127.0.0.1 mysite.com

這是用來告訴你的電腦指定mysite.com hostname指向你的本地機器。如果你使用Windows,你的hosts文件在 C:\Winwows\ System32\Drivers\etc\hosts

為了驗證你的host重定向是否可用,在瀏覽器中打開 http://mysite.com:8000/account/login/ 。如果你看到你的應用的登錄頁面,host重定向已經可用。

使用Facebook認證(authentication)

(譯者註:以下的幾種社交認證操作步驟可能已經過時,請根據實際情況操作)
為了讓你的用戶能夠使用他們的Facebook賬號來登錄你的網站,在項目settings.py文件中的AUTHENTICATION_BACKENDS設置中添加如下內容:

'social.backends.facebook.Facebook2OAuth2',

為了

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文由博主原創,轉載請註明出處:我的博客-知乎爬蟲之爬蟲流程設計 git爬蟲項目地址(關註和star在哪裡~~):https://github.com/MatrixSeven/ZhihuSpider (已完結) 附贈之前爬取的數據一份(mysql): 鏈接:https://github.com/Ma ...
  • 要知道什麼是智能指針,首先瞭解什麼稱為 “資源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“資源分配即初始化” 在《C++ Primer》這樣解釋的,“通過定義一個類來封裝資源的分配和釋放,可以保證正確釋放資源” 核心 ...
  • 結果: ...
  • 一. 異常的定義 在《java編程思想》中這樣定義 異常:阻止當前方法或作用域繼續執行的問題。雖然java中有異常處理機制,但是要明確一點,決不應該用"正常"的態度來看待異常。絕對一點說異常就是某種意義上的錯誤,就是問題,它可能會導致程式失敗。之所以java要提出異常處理機制,就是要告訴開發人員,... ...
  • 一、回調機制概述 回調機制在JAVA代碼中一直遇到,但之前不懂其原理,幾乎都是繞著走。俗話說做不願意做的事情叫做突破,故誕生了該文章,算是新年的新氣象,新突破! 回調機制是什麼?其實回調機制一直在我們身邊存在著,只是我們習慣了存在就未曾察覺,懂得其原理就很簡單了。 先打個比方,設置場景如下,教師,成 ...
  • java,exe是java虛擬機 javadoc.exe用來製作java文檔 jdb.exe是java的調試器 javaprof,exe是剖析工具 解析一: sleep是線程類(Thread)的方法,執行此方法會導致當前此線程暫停指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時後會自動恢復 ...
  • 因為第一次用這個新框架做項目,不太熟悉,就找了angular-cli這個腳手架來搭建項目。 安裝了好多次,看了好多博文(博客園、csdn、腳本之家等),終於成功了。 依據本寶寶幫多位小伙伴安裝成功的經驗,現總結安裝angular-cli過程如下: 1、設置淘寶鏡像,在 .npmrc文件(該... ...
  • 我們先實現從指定路徑讀取圖片然後輸出到頁面的功能。 先準備一張圖片imgs/dog.jpg。 file.js裡面繼續添加readImg方法,在這裡註意讀寫的時候都需要聲明'binary'。(file.js 在上一篇文章nodejs進階3-路由處理中有完整的內容) 伺服器創建代碼如下,註意在發送請求頭 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...