# 第三節:權限和分組
# 權限和分組
## 登錄、注銷和登錄限制:
### 登錄
在使用`authenticate`進行驗證后,如果驗證通過了。那么會返回一個`user`對象,拿到`user`對象后,可以使用`django.contrib.auth.login`進行登錄。示例代碼如下:
```
<pre class="calibre12">```
user = authenticate(username=username, password=password)
<span class="hljs-keyword">if</span> user <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">None</span>:
<span class="hljs-keyword">if</span> user.is_active:
login(request, user)
```
```
### 注銷:
注銷,或者說退出登錄。我們可以通過`django.contrib.auth.logout`來實現。他會清理掉這個用戶的`session`數據。
### 登錄限制:
有時候,某個視圖函數是需要經過登錄后才能訪問的。那么我們可以通過`django.contrib.auth.decorators.login_required`裝飾器來實現。示例代碼如下:
```
<pre class="calibre12">```
<span class="hljs-keyword">from</span> django.contrib.auth.decorators <span class="hljs-keyword">import</span> login_required
<span class="hljs-title"># 在驗證失敗后,會跳轉到/accounts/login/這個url頁面</span>
<span class="hljs-class">@login_required(login_url='/accounts/login/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">my_view</span><span class="hljs-params">(request)</span>:</span>
<span class="hljs-keyword">pass</span>
```
```
- - - - - -
## 權限:
`Django`中內置了權限的功能。他的權限都是針對表或者說是模型級別的。比如對某個模型上的數據是否可以進行增刪改查操作。他不能針對數據級別的,比如對某個表中的某條數據能否進行增刪改查操作(如果要實現數據級別的,考慮使用`django-guardian`)。創建完一個模型后,針對這個模型默認就有三種權限,分別是增/刪/改/。可以在執行完`migrate`命令后,查看數據庫中的`auth_permission`表中的所有權限。

其中的`codename`表示的是權限的名字。`name`表示的是這個權限的作用。
### 通過定義模型添加權限:
如果我們想要增加新的權限,比如查看某個模型的權限,那么我們可以在定義模型的時候在`Meta`中定義好。示例代碼如下:
```
<pre class="calibre12">```
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Article</span><span class="hljs-params">(models.Model)</span>:</span>
title = models.CharField(max_length=<span class="hljs-params">100</span>)
content = models.TextField()
author = models.ForeignKey(get_user_model(),on_delete=models.CASCADE)
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Meta</span>:</span>
permissions = (
(<span class="hljs-string">'view_article'</span>,<span class="hljs-string">'can view article'</span>),
)
```
```
### 通過代碼添加權限:
權限都是`django.contrib.auth.Permission`的實例。這個模型包含三個字段,`name`、`codename`以及`content_type`,其中的`content_type`表示這個`permission`是屬于哪個`app`下的哪個`models`。用`Permission`模型創建權限的代碼如下:
```
<pre class="calibre12">```
<span class="hljs-keyword">from</span> django.contrib.auth.models <span class="hljs-keyword">import</span> Permission,ContentType
<span class="hljs-keyword">from</span> .models <span class="hljs-keyword">import</span> Article
content_type = ContentType.objects.get_for_model(Article)
permission = Permission.objects.create(name=<span class="hljs-string">'可以編輯的權限'</span>,codename=<span class="hljs-string">'edit_article'</span>,content_type=content_type)
```
```
### 用戶與權限管理:
權限本身只是一個數據,必須和用戶進行綁定,才能起到作用。`User`模型和權限之間的管理,可以通過以下幾種方式來管理:
1. `myuser.user_permissions.set(permission_list)`:直接給定一個權限的列表。
2. `myuser.user_permissions.add(permission,permission,...)`:一個個添加權限。
3. `myuser.user_permissions.remove(permission,permission,...)`:一個個刪除權限。
4. `myuser.user_permissions.clear()`:清除權限。
5. `myuser.has_perm('<app_name>.<codename>')`:判斷是否擁有某個權限。權限參數是一個字符串,格式是`app_name.codename`。
6. `myuser.get_all_permissons()`:獲取所有的權限。
### 權限限定裝飾器:
使用`django.contrib.auth.decorators.permission_required`可以非常方便的檢查用戶是否擁有這個權限,如果擁有,那么就可以進入到指定的視圖函數中,如果不擁有,那么就會報一個`400`錯誤。示例代碼如下:
```
<pre class="calibre12">```
<span class="hljs-keyword">from</span> django.contrib.auth.decorators <span class="hljs-keyword">import</span> permission_required
<span class="hljs-class">@permission_required('front.view_article')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">my_view</span><span class="hljs-params">(request)</span>:</span>
...
```
```
- - - - - -
## 分組:
權限有很多,一個模型就有最少三個權限,如果一些用戶擁有相同的權限,那么每次都要重復添加。這時候分組就可以幫我們解決這種問題了,我們可以把一些權限歸類,然后添加到某個分組中,之后再把和把需要賦予這些權限的用戶添加到這個分組中,就比較好管理了。分組我們使用的是`django.contrib.auth.models.Group`模型, 每個用戶組擁有`id`和`name`兩個字段,該模型在數據庫被映射為`auth_group`數據表。
### 分組操作:
1. `Group.object.create(group_name)`:創建分組。
2. `group.permissions`:某個分組上的權限。多對多的關系。
- `group.permissions.add`:添加權限。
- `group.permissions.remove`:移除權限。
- `group.permissions.clear`:清除所有權限。
- `user.get_group_permissions()`:獲取用戶所屬組的權限。
3. `user.groups`:某個用戶上的所有分組。多對多的關系。
- - - - - -
## 在模板中使用權限:
在`settings.TEMPLATES.OPTIONS.context_processors`下,因為添加了`django.contrib.auth.context_processors.auth`上下文處理器,因此在模板中可以直接通過`perms`來獲取用戶的所有權限。示例代碼如下:
```
<pre class="calibre12">```
```
```
- Introduction
- 第一章:學前準備
- 第一節:虛擬環境
- 第二節:準備工作
- 第三節:Django介紹
- 第四節:URL組成部分
- 第二章:URL與視圖
- 第一節:第一個Django項目
- 第二節:視圖與URL分發器
- 第三章:模板
- 第一節:模板介紹
- 第二節:模板變量
- 第三節:常用標簽
- 第四節:常用過濾器
- 第五節:自定義過濾器
- 第七節:模版結構優化
- 第八節:加載靜態文件
- 第四章:數據庫
- 第一節:MySQL相關軟件
- 第二節:數據庫操作
- 第三節:ORM模型
- 第四節:模型常用字段
- 第五節:外鍵和表關系
- 第六節:增刪改查操作
- 第七節:查詢操作
- 第八節:QuerySet API
- 第九節:ORM模型遷移
- 第十節:ORM作業
- 第十一節:ORM作業參考答案
- 第十二節:Pycharm連接數據庫
- 第五章:視圖高級
- 第一節:限制請求method
- 第二節:頁面重定向
- 第三節:HttpRequest對象
- 第四節:HttpResponse對象
- 第五節:生成CSV文件
- 第六節:類視圖
- 第七節:錯誤處理
- 第六章:表單
- 第一節:表單概述
- 第二節:用表單驗證數據
- 第三節:ModelForm
- 第四節:文件上傳
- 第七章:cookie和session
- 第八章:上下文處理器和中間件
- 第一節:上下文處理器
- 第二節:中間件
- 第九章:安全
- 第一節:CSRF攻擊
- 第二節:XSS攻擊
- 第三節:點擊劫持攻擊
- 第四節:SQL注入
- 第十章:信號
- 第一節:什么是信號
- 第十一章:驗證和授權
- 第一節:概述
- 第二節:用戶對象
- 第三節:權限和分組
- 第十二章:Admin系統
- 第十三章:Django的緩存
- 第十四章:memcached
- 第十五章:Redis