Django Authentication 用戶認證系統
一、 Django的認證系統
Django自帶一個用戶認證系統,用於處理用戶賬戶、群組、許可和基於cookie的用戶會話。
1.1 概覽
Django的認證系統包含了身份驗證和權限管理兩部分。簡單地說,身份驗證用於核實某個用戶是否是合法用戶,權限管理則是決定一個合法用戶具有哪些權限。這裏,“身份驗證”這個詞同時代指上面兩部分的含義。
系統主要包括:
- 用戶
- 許可
- 組
- 可配置的密碼哈希系統
- 用於用戶登錄或者限制訪問的表單和視圖工具
- 可插拔的後端
類似下面的問題,請使用第三方包:
- 密碼強度檢查
- 登錄請求限制
- 第三方認證
1.2 安裝
默認情況下,使用django-admin startproject命令後,認證相關的模塊已經自動添加到settings文件內了,如果沒有的話,請手動添加。
在 INSTALLED_APPS配置項中:
- ‘django.contrib.auth‘: 包含認證框架的核心以及默認模型
- ‘django.contrib.contenttypes‘:內容類型系統,用於給模型關聯許可
在MIDDLEWARE配置項中:
- SessionMiddleware:通過請求管理會話
- AuthenticationMiddleware:將會話和用戶關聯
當配置正確後,運行manage.py migrate命令,創建用戶認證系統相關的數據庫表以及分配預定義的權限。
二、 使用Django的認證系統
2.1 用戶對象
默認的用戶包含下面的屬性:
- username
- password
- first_name
- last_name
2.1.1 創建用戶
最直接的辦法是使用 create_user()功能:
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user(‘john‘, ‘[email protected]‘, ‘johnpassword‘)
# 這時,user是一個User類的實例,已經保存在了數據庫內,你可以隨時修改它的屬性,例如:
>>> user.last_name = ‘Lennon‘
>>> user.save()
如果你已經啟用了Django的admin站點,你也可以在web頁面上創建用戶。
2.1.2 創建超級用戶
使用createsuperuser命令
$ python manage.py createsuperuser --username=joe [email protected]
根據提示輸入名字、密碼和郵箱地址。
2.1.3 修改密碼
Django默認會對密碼進行加密,因此,不要企圖對密碼進行直接操作。這也是為什麽要使用一個幫助函數來創建用戶的原因。
要修改密碼,有兩個辦法:
- 使用命令行: manage.py changepassword username。如果不提供用戶名,則會嘗試修改當前系統用戶的密碼。
- 使用set_password()方法:
from django.contrib.auth.models import User
u = User.objects.get(username=‘john‘)
u.set_password(‘new password‘)
u.save()
同樣可以在admin中修改密碼。
Django提供了views和forms,方便用戶自己修改密碼。
修改密碼後,用戶的所有當前會話將被註銷。
2.1.4 用戶驗證
authenticate(**credentials)[source]:
通常接收username與password作為參數進行認證。在認證後端中,有一項通過則返回一個User類對象,一項都沒通過或者拋出了PermissionDenied異常,則返回一個None。例如:
from django.contrib.auth import authenticate
user = authenticate(username=‘john‘, password=‘secret‘)
if user is not None:
# A backend authenticated the credentials
else:
# No backend authenticated the credentials
2.2 權限與授權
Django提供了一個權限系統用於它的admin站點,當然你也可以在你的代碼中使用。
使用方法:
- 必須有“add”授權的用戶才可以訪問add頁面
- 必須有“change”授權的用戶才可以訪問change list頁面
- 必須有“delete”授權的用戶才可以刪除對象
ModelAdmin類提供了 has_add_permission(),has_change_permission()和has_delete_permission()三個方法。User表的對象有兩個多對多的字段,groups和user_permissions,可以像普通的model一樣訪問他們。
myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()
2.2.1 默認權限
默認情況下,使用manage.py migrate命令時,Django會給每個已經存在的model添加默認的權限。
假設你現在有個app叫做foo,有個model叫做bar,使用下面的方式可以測試默認權限:
add: user.has_perm(‘foo.add_bar‘)
change: user.has_perm(‘foo.change_bar‘)
delete: user.has_perm(‘foo.delete_bar‘)
2.2.2 組
Django提供了一個django.contrib.auth.models.Group模型,該model可用於給用戶分組,實現批量管理。用戶和組屬於多對多的關系。用戶自動具有所屬組的所有權限。
2.2.3 在代碼中創建權限
例如,你可以為myapp中的BlogPost模型添加一個can_publish權限。
from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
codename=‘can_publish‘,
name=‘Can Publish Posts‘,
content_type=content_type,
)
然後,你可以通過User模型的user_permissions屬性或者Group模型的permissions屬性為用戶添加該權限。
2.2.4 權限緩存
權限檢查後,會被緩存在用戶對象中。參考下面的例子:
from django.contrib.auth.models import Permission, User
from django.shortcuts import get_object_or_404
def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# any permission check will cache the current set of permissions
user.has_perm(‘myapp.change_bar‘)
permission = Permission.objects.get(codename=‘change_bar‘)
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm(‘myapp.change_bar‘) # False
# Request new instance of User
# Be aware that user.refresh_from_db() won‘t clear the cache.
user = get_object_or_404(User, pk=user_id)
# Permission cache is repopulated from the database
user.has_perm(‘myapp.change_bar‘) # True
...
2.3 在Web請求中的認證
Django使用session和中間件在請求對象中鉤住認證系統。
每一次請求中都包含一個request.user屬性。如果該用戶未登陸,該屬性的值是AnonymousUser,如果已經登錄,該屬性就是一個User模型的實例。
可以使用is_authenticated方法進行判斷,如下:
if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
2.3.1 如何登錄用戶
login(request, user, backend=None)[source]:
在視圖中,使用login()方法登錄用戶。它接收一個HttpRequest參數和一個User對象參數。該方法會把用戶的ID保存在Django的session中。下面是一個認證和登陸的例子:
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST[‘username‘]
password = request.POST[‘password‘]
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
# 跳轉到成功頁面
...
else:
# 返回一個非法登錄的錯誤頁面
...
2.3.2 如何註銷用戶
logout(request)[source]:
from django.contrib.auth import logout
def logout_view(request):
logout(request)
# Redirect to a success page.
註意,被logout的用戶如何沒登錄,不會拋出錯誤。
一旦logout,當前請求中的session數據都會被清空。
2.3.3 登陸用戶訪問限制
原始的辦法:
在request.user.is_authenticated中重定向到登錄頁面,如下所示:
from django.conf import settings
from django.shortcuts import redirect
def my_view(request):
if not request.user.is_authenticated:
return redirect(‘%s?next=%s‘ % (settings.LOGIN_URL, request.path))
# ...
或者顯示一個錯誤信息:
from django.shortcuts import render
def my_view(request):
if not request.user.is_authenticated:
return render(request, ‘myapp/login_error.html‘)
# ...
使用裝飾器
login_required(redirect_field_name=‘next‘, login_url=None)[source]
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
該裝飾器工作機制:
- 如果用戶未登陸,重定向到settings.LOGIN_URL,傳遞當前絕對路徑作為url字符串的參數,例如:/accounts/login/?next=/polls/3/
- 如果用戶已經登錄,執行正常的視圖
此時,默認的url中使用的參數是“next”,如果你想使用自定義的參數,請修改login_required()的redirect_field_name參數,如下所示:
from django.contrib.auth.decorators import login_required
@login_required(redirect_field_name=‘my_redirect_field‘)
def my_view(request):
...
如果你這麽做了,你還需要重新定制登錄模板,因為它引用了redirect_field_name變量。
login_required()方法還有一個可選的longin_url參數。例如:
from django.contrib.auth.decorators import login_required
@login_required(login_url=‘/accounts/login/‘)
def my_view(request):
...
註意:如果不指定login_url參數,請確保你的settings.LOGIN_URL和登陸視圖保持正確的關聯。例如:
from django.contrib.auth import views as auth_views
url(r‘^accounts/login/$‘, auth_views.login),
使用LoginRequired mixin
通過繼承LoginRequiredMixin類的方式。
在多繼承時,該類必須是最左邊的父類。
class LoginRequiredMixin(New in Django 1.9.)
根據raise_exception參數的不同,對於未登陸的用戶請求,響應不同的結果。
from django.contrib.auth.mixins import LoginRequiredMixin
class MyView(LoginRequiredMixin, View):
login_url = ‘/login/‘
redirect_field_name = ‘redirect_to‘
進行測試,根據結果決定動作
你也可以直接在視圖中進行過濾:
from django.shortcuts import redirect
def my_view(request):
if not request.user.email.endswith(‘@example.com‘):
return redirect(‘/login/?next=%s‘ % request.path)
# ...
- user_passes_test(test_func,login_url=None,redirect_field_name=‘next‘)[source]
該裝飾器當調用的返回值是Fasle的時候重定向。
from django.contrib.auth.decorators import user_passes_test
def email_check(user):
return user.email.endswith(‘@example.com‘)
@user_passes_test(email_check)
def my_view(request):
...
對於上面的例子,email_check接收一個User對象作為參數,當其返回值是True時,允許執行下面的my_view視圖,否則不允許。
user_passes_test()有兩個可選的參數:login_url和redirect_field_name。前者是跳轉的url後者是url參數字符串。例如:
@user_passes_test(email_check, login_url=‘/login/‘)
def my_view(request):
...
- class UserPassesTestMixin
繼承該類,重寫test_func()方法:
from django.contrib.auth.mixins import UserPassesTestMixin
class MyView(UserPassesTestMixin, View):
def test_func(self):
return self.request.user.email.endswith(‘@example.com‘)
也可以重寫get_test_func()方法,指定自定義的名稱用於替代默認的test_func。
權限需求裝飾器
permission_required(perm, login_url=None, raise_exception=False)[source]
from django.contrib.auth.decorators import permission_required
@permission_required(‘polls.can_vote‘)
def my_view(request):
...
類似has_perm()方法。權限的格式是<app label>.<permission codename>
。
可選的longin_url參數:
from django.contrib.auth.decorators import permission_required
@permission_required(‘polls.can_vote‘, login_url=‘/loginpage/‘)
def my_view(request):
...
raise_exception參數如果給予,裝飾器會拋出PermissionDenied異常,並且用403頁面代替重定向的登陸頁面。例如:
from django.contrib.auth.decorators import login_required, permission_required
@login_required
@permission_required(‘polls.can_vote‘, raise_exception=True)
def my_view(request):
...
PermissionRequiredMixin類
同上面的loginrequiredmixin類似。
from django.contrib.auth.mixins import PermissionRequiredMixin
class MyView(PermissionRequiredMixin, View):
permission_required = ‘polls.can_vote‘
# Or multiple of permissions:
permission_required = (‘polls.can_open‘, ‘polls.can_edit‘)
可以自定義重寫get_permission_required()和has_permission()方法
2.3.4 在基於類的視圖中重定向未授權的請求
class AccessMixin:
-
login_url
get_login_url()方法的默認回調函數。 -
permission_denied_message
拒絕訪問的提示信息。默認是空字符串。 -
redirect_field_name
get_redirect_field_name()的返回值. 默認是"next". -
raise_exception
拋出異常。默認為False。 -
get_login_url()
-
get_permission_denied_message()
-
get_redirect_field_name()
-
handle_no_permission()?
2.3.5 認證視圖
Django沒有為認證視圖提供默認的模板,你需要自己創建。
使用視圖
有很多種辦法實現這些視圖,最簡單的是使用Django提供的django.contrib.auth.urls,將它添加到URLconf文件中:
urlpatterns = [
url(‘^‘, include(‘django.contrib.auth.urls‘)),
]
這就相當於添加了下面的URL模式:
^login/$ [name=‘login‘]
^logout/$ [name=‘logout‘]
^password_change/$ [name=‘password_change‘]
^password_change/done/$ [name=‘password_change_done‘]
^password_reset/$ [name=‘password_reset‘]
^password_reset/done/$ [name=‘password_reset_done‘]
^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name=‘password_reset_confirm‘]
^reset/done/$ [name=‘password_reset_complete‘]
其中,方括號裏的是url的別名。
當然,也可以使用自定義的URL,例如:
from django.contrib.auth import views as auth_views
urlpatterns = [
url(‘^change-password/$‘, auth_views.password_change),
]
這些views有一些可選的參數。例如template_name,用於指定視圖需要使用的html模板,看下面的例子:
urlpatterns = [
url(
‘^change-password/$‘, auth_views.password_change,
{‘template_name‘: ‘change-password.html‘}
),
]
所有的這類views都返回一個TemplateResponse實例,對於自定義views可以將Django提供的view封裝起來使用,例如:
from django.contrib.auth import views
def change_password(request):
template_response = views.password_change(request)
# Do something with `template_response`
return template_response
所有的認證視圖
下面是django.contrib.auth模塊包含的所有視圖:
login(request, template_name=registration/login.html
, redirect_field_name=‘next‘, authentication_form=AuthenticationForm, current_app=None, extra_context=None, redirect_authenticated_user=False)
登錄視圖
URL name:login (該視圖對應的訪問地址,下同)
可選參數:
template_name: 登錄頁面html文件名。默認為registration/login.html。
redirect_field_name: 用於登錄URL路徑的參數關鍵字,默認是“next”。
authentication_form:用於認證的調用,默認是AuthenticationForm。
current_app: 2.0版本中將被移除,用request.current_app代替。
extra_context: 額外的數據字典
redirect_authenticated_user:一個布爾值,用於控制已登陸用戶是否可以訪問登錄頁面。默認是False。
django.contrib.auth.views.login視圖的工作機制是:
使用GET請求時,顯示一個登陸表單,用戶可以輸入登錄信息。
使用POST請求時,攜帶用戶提供的登陸信息,進行用戶驗證。如果驗證成功,重定向到next參數指定的url地址(如果未指定next參數,則使用settings.LOGIN_REDIRECT_URL中配置的地址,該地址默認為/accounts/profile/),如果不成功,繼續顯示表單頁面。
Django不提供registration/login.html模板文件,需要自己編寫。該模板有4個環境變量:
- form:一個表示AuthenticationForm的Form對象
- next:登錄成功後重定向的url地址
- site:當前的Site,根據SITE_ID設置。如果沒有安裝site框架,則被設置為一個RequestSite的實例,它將從HttpRequest中導出site名和域名。
- site_name:site.name的別名。如果沒安裝site框架,它將被設置為request.META[‘SERVER_NAME‘]的值。
也可以不使用默認的registration/login.html模板,而是指定別的模板,使用template_name參數,如下:
url(r‘^accounts/login/$‘, auth_views.login, {‘template_name‘: ‘myapp/login.html‘}),
這裏有一個registration/login.html模板的簡單例子(假定你已經有了base.html文件)。
{% extends "base.html" %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn‘t match. Please try again.</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account doesn‘t have access to this page. To proceed,
please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %}
<form method="post" action="{% url ‘login‘ %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{# Assumes you setup the password_reset view in your URLconf #}
<p><a href="{% url ‘password_reset‘ %}">Lost password?</a></p>
{% endblock %}
如果使用自定義認證系統,可以通過authentication_form參數,指定你自定義的認證form顯示在登錄頁面中。這個form必須接受一個request關鍵字參數在它的__init__方法中,並且提供一個get_user()方法用於返回通過認證的user對象。
logout(request, next_page=None, template_name=‘registration/logged_out.html‘, redirect_field_name=‘next‘, current_app=None, extra_context=None)
註銷視圖
URL name: logout
可選參數:
- next_page: 註銷後跳轉的頁面。默認是settings.LOGOUT_REDIRECT_URL。
- template_name: 註銷後跳轉的頁面html文件.默認是registration/logged_out.html
- redirect_field_name: 同上
- current_app: 同上
- extra_context:同上
模板變量:
- title:字符串“Logged out”
- site:同上
- site_name:同上
logout_then_login(request, login_url=None, current_app=None, extra_context=None)
註銷用戶,並返回登錄頁面。
URL name:未設置
可選參數:
- login_url:同上
- current_app: 同上
- extra_context:同上
password_change(request, template_name=‘registration/password_change_form.html‘, post_change_redirect=None, password_change_form=PasswordChangeForm, current_app=None, extra_context=None)?
用戶修改密碼的頁面
URL name:password_change
可選參數:
- template_name:用於顯示修改密碼表單的頁面文件。默認是registration/password_change_form.html。
- post_change_redirect:成功修改後跳轉的url
- password_change_form:自定義的“change password”表單,它必須接收一個user關鍵字參數。默認為PasswordChangeForm。
- current_app: 同上
- extra_context:同上
模板變量:
- form:修改密碼的表單
password_change_done(request, template_name=‘registration/password_change_done.html‘, current_app=None, extra_context=None)
用戶修改完密碼後的頁面。
URL name: password_change_done
可選參數:
- template_name:用於顯示修改密碼表單的頁面文件。默認是registration/password_change_form.html。
- current_app: 同上
- extra_context:同上
password_reset(request, template_name=‘registration/password_reset_form.html‘, email_template_name=‘registration/password_reset_email.html‘, subject_template_name=‘registration/password_reset_subject.txt‘, password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None, extra_email_context=None)?
生成一個一次性的連接,並將該連接發送到用戶註冊的郵箱地址,用戶通過改地址重置他的密碼。
為了防止潛在的攻擊,如果提供的郵件地址在系統中不存在,視圖不會發送郵件,用戶也不會受到任何的錯誤信息提示。如果想要提供錯誤信息的話,繼承PasswordResetForm類,並使用password_reset_form參數。
URL name: password_reset
可選參數:
- template_name: 同上。默認是registration/password_reset_form.html。
- email_template_name:發送攜帶重置密碼連接的郵件的頁面。默認是registration/password_reset_email.html。
- subject_template_name:郵件的主題,默認是registration/password_reset_subject.txt。
- password_reset_form: 同上
- token_generator:檢查一次性連接的類的實例。默認是default_token_generator,它是django.contrib.auth.tokens.PasswordResetTokenGenerator的一個實例。
- post_reset_redirect: 同上
- from_email: 發件人地址。默認是DEFAULT_FROM_EMAIL。
- current_app: 同上
- extra_context:同上
- html_email_template_name: 默認情況下HTML email不發送。
- extra_email_context: email模板中額外的數據字典。
模板變量:
- form:同上
email模板變量:
- email:user.email的別名
- user:當前user。只有有效的用戶才可以重置他們的密碼(User.is_active is True)。
- site_name:同上
- domain:site.domain的別名。如果沒有安裝site框架,則為request.get_host()。
- protocol: http或者https協議
- uid: 用戶的主鍵,基於64位。
- token: 用於檢查重置連接合法性的令牌
一個簡單的registration/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 %}
password_reset_done(request, template_name=‘registration/password_reset_done.html‘, current_app=None, extra_context=None)
密碼重置後的跳轉頁面
URL name: password_reset_done
可選參數:
- template_name: 同上。默認是registration/password_reset_done.html。
- current_app: 同上
- extra_context:同上
password_reset_confirm(request, uidb64=None, token=None, template_name=‘registration/password_reset_confirm.html‘, token_generator=default_token_generator, set_password_form=SetPasswordForm, post_reset_redirect=None, current_app=None, extra_context=None)
顯示一個輸入新密碼的表單
URL name: password_reset_confirm
可選參數:
- uidb64: 同上,默認為None。
- token: 檢查密碼是否合法的令牌,默認為None.
- template_name: 同上,默認為registration/password_reset_confirm.html.
- token_generator: 同上
- set_password_form: 用於設置密碼的表單。默認為SetPasswordForm。
- post_reset_redirect: 同上,默認為None。
- current_app: 同上
- extra_context: 同上
模板變量:
- form: 同上
- validlink: 布爾值。鏈接合法則為True。
password_reset_complete(request, template_name=‘registration/password_reset_complete.html‘, current_app=None, extra_context=None)
提示用戶密碼已經成功修改
URL name: password_reset_complete
可選參數:
- template_name: 同上,默認為registration/password_reset_confirm.html.
- current_app: 同上
- extra_context: 同上
2.3.6 有用的函數
redirect_to_login(next, login_url=None, redirect_field_name=‘next‘)
重定向到登錄頁面,登錄成功後跳轉到指定的url。
必須參數:next,登錄成功後跳轉的url
可選參數:longin_url和redirect_field_name
2.3.7 內置表單
如果你不想使用內置的視圖,但又不想編寫表單,認證系統提供了內置的表單供你直接使用,它們位於django.contrib.auth.forms。
class AdminPasswordChangeForm
admin中用於修改用戶密碼的表單。user是它的第一位置參數。
class AuthenticationForm
登錄表單,request是它的第一位置參數。
confirm_login_allowed(user):默認情況下,它拒絕is_active標識為False的用戶。要修改這個規則,你需要繼承AuthenticationForm類,並重寫confirm_login_allowed()方法。如果給予的用戶沒有登錄,它應該拋出一個ValidationError異常。
例如,允許所有用戶登錄,不管它是否active:
from django.contrib.auth.forms import AuthenticationForm
class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm):
def confirm_login_allowed(self, user):
pass
或者只允許某些狀態的用戶登錄:
class PickyAuthenticationForm(AuthenticationForm):
def confirm_login_allowed(self, user):
if not user.is_active:
raise forms.ValidationError(
_("This account is inactive."),
code=‘inactive‘,
)
if user.username.startswith(‘b‘):
raise forms.ValidationError(
_("Sorry, accounts starting with ‘b‘ aren‘t welcome here."),
code=‘no_b_users‘,
)
class PasswordChangeForm
用戶修改自己密碼的表單
class PasswordResetForm
一個表單,用於生成和發送帶有一次性連接的郵件,幫助用戶重置密碼。
send_email(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)
發送郵件的方法。
參數:
- subject_template_name – 主題模板
- email_template_name – 郵件主題模板
- context – 傳遞給subject_template, email_template和html_email_template 的數據
- from_email – 發件人
- to_email – 收件人
- html_email_template_name
class SetPasswordForm
設置密碼的表單
class UserChangeForm
admin中修改用戶信息和權限的表單
class UserCreationForm
創建新用戶的ModelForm。它有3個字段,username、password1和password2.
2.3.8 模板中的認證數據
用戶
渲染一個RequestContext模板時,當前已登陸的用戶,或者一個User實例,或者一個 AnonymousUser實例,都被保存在模板的變量{{ user }}中。例如:
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
如果不是使用的RequestContext,這些變量將不可用。
權限
當前登陸用戶的權限保存在模板變量 {{ perms }}中。它是一個django.contrib.auth.context_processors.PermWrapper的實例。
對於{{ perms }}對象,單級屬性查詢相當於User.has_module_perms的功能。例如:
{{ perms.foo }},如果登陸用戶有任何foo的權限,該變量就等於True。
雙級屬性查詢相當於User.has_perm。例如:{{ perms.foo.can_vote }}
因此,你可以在if語句中使用它們,如下面的例子所示:
{% if perms.foo %}
<p>You have permission to do something in the foo app.</p>
{% if perms.foo.can_vote %}
<p>You can vote!</p>
{% endif %}
{% if perms.foo.can_drive %}
<p>You can drive!</p>
{% endif %}
{% else %}
<p>You don‘t have permission to do anything in the foo app.</p>
{% endif %}
還可以使用關鍵字“in”,進行範圍判斷:
{% if ‘foo‘ in perms %}
{% if ‘foo.can_vote‘ in perms %}
<p>In lookup works, too.</p>
{% endif %}
{% endif %}
2.4 在admin站點中管理用戶
當django.contrib.admin與django.contrib.auth都被安裝時,可以在admin站點中方便的對用戶、組和權限進行管理。
轉載自:http://www.cnblogs.com/feixuelove1009/p/6253553.html
Django Authentication 用戶認證系統