Django-DRF組件學習-其餘學習

1.認證Authentication

能夠在配置文件中配置全局默認的認證方案css

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',  # session認證
        'rest_framework.authentication.BasicAuthentication',   # 基本認證
    )
}

也能夠在每一個視圖中經過設置authentication_classess屬性來設置html

from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.views import APIView
​
class ExampleView(APIView):
    # 類屬性
    authentication_classes = [SessionAuthentication, BasicAuthentication]
    ...

認證失敗會有兩種可能的返回值:前端

  • 401 Unauthorized 未認證python

  • 403 Permission Denied 權限被禁止git

2.權限permissions

權限控制能夠限制用戶對於視圖的訪問和對於具體數據對象的訪問。github

  • 在執行視圖的dispatch()方法前,會先進行視圖訪問權限的判斷數據庫

  • 在經過get_object()獲取具體對象時,會進行模型對象訪問權限的判斷django

2.1 使用

能夠在配置文件中全局設置默認的權限管理類,如json

REST_FRAMEWORK = {
    ....
    
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

若是未指明,則採用以下默認配置bootstrap

'DEFAULT_PERMISSION_CLASSES': (
   'rest_framework.permissions.AllowAny',
)

也能夠在具體的視圖中經過permission_classes屬性來設置,如

from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = (IsAuthenticated,)
    ...

2.2 提供的權限

  • AllowAny 容許全部用戶

  • IsAuthenticated 僅經過認證的用戶

  • IsAdminUser 僅管理員用戶

  • IsAuthenticatedOrReadOnly 已經登錄認證的用戶能夠對數據進行增刪改操做,沒有登錄認證的只能查看數據。

2.3 舉例

from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView

class StudentAPIView(RetrieveAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    authentication_classes = [SessionAuthentication]
    permission_classes = [IsAuthenticated]

2.4 自定義權限

如需自定義權限,需繼承rest_framework.permissions.BasePermission父類,並實現如下兩個任何一個方法或所有

  • .has_permission(self, request, view)

    是否能夠訪問視圖, view表示當前視圖對象

     

  • .has_object_permission(self, request, view, obj)

    是否能夠訪問數據對象, view表示當前視圖, obj爲數據對象

例如:

在當前子應用下,建立一個權限文件permissions.py中聲明自定義權限類:

from rest_framework.permissions import BasePermission

class IsXiaoMingPermission(BasePermission):
    def has_permission(self, request, view):
        if( request.user.username == "xiaoming" ):
            return True
from rest_framework.permissions import BasePermission

class IsXiaoMingPermission(BasePermission):
    def has_permission(self, request, view):
        if( request.user.username == "xiaoming" ):
            return True

3.限流Throttling

能夠對接口訪問的頻次進行限制,以減輕服務器壓力。

通常用於付費購買次數,投票等場景使用.

3.1 使用

能夠在配置文件中,使用DEFAULT_THROTTLE_CLASSESDEFAULT_THROTTLE_RATES進行全局配置,

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day',
        'user': '1000/day'
    }
}

DEFAULT_THROTTLE_RATES 可使用 second, minute, hourday來指明週期。

也能夠在具體視圖中經過throttle_classess屬性來配置,如

from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView

class ExampleView(APIView):
    throttle_classes = (UserRateThrottle,)
    ...

3.2 可選限流類

1) AnonRateThrottle

限制全部匿名未認證用戶,使用IP區分用戶。

使用DEFAULT_THROTTLE_RATES['anon'] 來設置頻次

2)UserRateThrottle

限制認證用戶,使用User id 來區分。

使用DEFAULT_THROTTLE_RATES['user'] 來設置頻次

3)ScopedRateThrottle

限制用戶對於每一個視圖的訪問頻次,使用ip或user id。

例如:

class ContactListView(APIView):
    throttle_scope = 'contacts'
    ...

class ContactDetailView(APIView):
    throttle_scope = 'contacts'
    ...

class UploadView(APIView):
    throttle_scope = 'uploads'
    ...
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.ScopedRateThrottle',
    ),
    'DEFAULT_THROTTLE_RATES': {
        'contacts': '1000/day',
        'uploads': '20/day'
    }
}

3.3 例子

全局配置中設置訪問頻率

'DEFAULT_THROTTLE_RATES': {
        'anon': '3/minute',
        'user': '10/minute'
    }
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.throttling import UserRateThrottle

class StudentAPIView(RetrieveAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    authentication_classes = [SessionAuthentication]
    permission_classes = [IsAuthenticated]
    throttle_classes = (UserRateThrottle,)

4.過濾filtering

******用的不少

對於列表數據可能須要根據字段進行過濾,咱們能夠經過添加django-fitlter擴展來加強支持。

pip install django-filter

在配置文件中增長過濾後端的設置:

INSTALLED_APPS = [
    ...
    'django_filters',  # 須要註冊應用,
]

REST_FRAMEWORK = {
    ...
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)

在視圖中添加filter_fields屬性,指定能夠過濾的字段

class StudentListView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    filter_fields = ('age', 'sex')

# 127.0.0.1:8000/four/students/?sex=1

5.排序

對於列表數據,REST framework提供了OrderingFilter過濾器來幫助咱們快速指明數據按照指定字段進行排序。

使用方法:

在類視圖中設置filter_backends,使用rest_framework.filters.OrderingFilter過濾器,REST framework會在請求的查詢字符串參數中檢查是否包含了ordering參數,若是包含了ordering參數,則按照ordering參數指明的排序字段對數據集進行排序。

前端能夠傳遞的ordering參數的可選字段值須要在ordering_fields中指明。

示例:

class StudentListView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = ('id', 'age')

# 127.0.0.1:8000/books/?ordering=-age
# -id 表示針對id字段進行倒序排序
# id  表示針對id字段進行升序排序

若是須要在過濾之後再次進行排序,則須要二者結合!

from rest_framework.generics import ListAPIView
from students.models import Student
from .serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
class Student3ListView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_fields = ('age', 'sex')
    # 由於局部配置會覆蓋全局配置,因此須要從新把過濾組件核心類再次聲明,
    # 不然過濾功能會失效
    filter_backends = [OrderingFilter,DjangoFilterBackend]
    ordering_fields = ('id', 'age')

6.分頁pagination

REST framework提供了分頁的支持。

咱們能夠在配置文件中設置全局的分頁方式,如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100  # 每頁數目
}

也可經過自定義Pagination類,來爲視圖添加不一樣分頁行爲。在視圖中經過pagination_clas屬性來指明。

class LargeResultsSetPagination(PageNumberPagination):
    page_size = 1000
    page_size_query_param = 'page_size'
    max_page_size = 10000
class BookDetailView(RetrieveAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    pagination_class = LargeResultsSetPagination

注意:若是在視圖內關閉分頁功能,只需在視圖內設置

pagination_class = None

6.1 可選分頁器

1) PageNumberPagination

前端訪問網址形式:

GET  http://127.0.0.1:8000/students/?page=4

能夠在子類中定義的屬性:

  • page_size 每頁數目

  • page_query_param 前端發送的頁數關鍵字名,默認爲"page"

  • page_size_query_param 前端發送的每頁數目關鍵字名,默認爲None

  • max_page_size 前端最多能設置的每頁數量

# 聲明分頁的配置類
from rest_framework.pagination import PageNumberPagination
class StandardPageNumberPagination(PageNumberPagination):
    # 默認每一頁顯示的數據量
    page_size = 2
    # 容許客戶端經過get參數來控制每一頁的數據量
    page_size_query_param = "size"
    max_page_size = 10
    # 自定義頁碼的參數名
    page_query_param = "p"class StudentAPIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    pagination_class = StandardPageNumberPagination
​
# 127.0.0.1/four/students/?p=1&size=5

2)LimitOffsetPagination

前端訪問網址形式:

GET http://127.0.0.1/four/students/?limit=100&offset=400

能夠在子類中定義的屬性:

  • default_limit 默認限制,默認值與PAGE_SIZE設置一直

  • limit_query_param limit參數名,默認'limit'

  • offset_query_param offset參數名,默認'offset'

  • max_limit 最大limit限制,默認None

from rest_framework.pagination import LimitOffsetPagination
class StandardLimitOffsetPagination(LimitOffsetPagination):
    # 默認每一頁查詢的數據量,相似上面的page_size
    default_limit = 2
    limit_query_param = "size"
    offset_query_param = "start"class StudentAPIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    # 調用頁碼分頁類
    # pagination_class = StandardPageNumberPagination
    # 調用查詢偏移分頁類
    pagination_class = StandardLimitOffsetPagination

7.異常處理exceptions

REST framework提供了異常處理,咱們能夠自定義異常處理函數。

from rest_framework.views import exception_handler
​
def custom_exception_handler(exc, context):
    # 先調用REST framework默認的異常處理方法得到標準錯誤響應對象
    response = exception_handler(exc, context)
​
    # 在此處補充自定義的異常處理
    if response is None:
        response.data['status_code'] = response.status_code
​
    return response

在配置文件中聲明自定義的異常處理

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}

若是未聲明,會採用默認的方式,以下

rest_frame/settings.py
REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}

例如:

補充上處理關於數據庫的異常

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework import status
from django.db import DatabaseError
​
def exception_handler(exc, context):
    response = drf_exception_handler(exc, context)
​
    if response is None:
        view = context['view']
        if isinstance(exc, DatabaseError):
            print('[%s]: %s' % (view, exc))
            response = Response({'detail': '服務器內部錯誤'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)
​
    return response
REST framework定義的異常
  • APIException 全部異常的父類

  • ParseError 解析錯誤

  • AuthenticationFailed 認證失敗

  • NotAuthenticated 還沒有認證

  • PermissionDenied 權限決絕

  • NotFound 未找到

  • MethodNotAllowed 請求方式不支持

  • NotAcceptable 要獲取的數據格式不支持

  • Throttled 超過限流次數

  • ValidationError 校驗失敗

也就是說,不少的沒有在上面列出來的異常,就須要咱們在自定義異常中本身處理了。

8.自動生成接口文檔

REST framework能夠自動幫助咱們生成接口文檔。

接口文檔以網頁的方式呈現。

自動接口文檔能生成的是繼承自APIView及其子類的視圖。

8.1 安裝依賴

REST framewrok生成接口文檔須要coreapi庫的支持。

pip install coreapi

8.2  設置接口文檔訪問路徑

在總路由中添加接口文檔路徑。

文檔路由對應的視圖配置爲rest_framework.documentation.include_docs_urls

參數title爲接口文檔網站的標題。

from rest_framework.documentation import include_docs_urls

urlpatterns = [
    ...
    path('docs/', include_docs_urls(title='站點頁面標題'))
]

8.3 文檔描述說明的定義位置

1) 單一方法的視圖,可直接使用類視圖的文檔字符串,如

class BookListView(generics.ListAPIView):
    """
    返回全部圖書信息.
    """

2)包含多個方法的視圖,在類視圖的文檔字符串中,分開方法定義,如

class BookListCreateView(generics.ListCreateAPIView):
    """
    get:
    返回全部圖書信息.
​
    post:
    新建圖書.
    """

3)對於視圖集ViewSet,仍在類視圖的文檔字符串中封開定義,可是應使用action名稱區分,如

class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    """
    list:
    返回圖書列表數據
​
    retrieve:
    返回圖書詳情數據
​
    latest:
    返回最新的圖書數據
​
    read:
    修改圖書的閱讀量
    """

8.4 訪問接口文檔網頁

瀏覽器訪問 127.0.0.1:8000/docs/,便可看到自動生成的接口文檔。

接口文檔頁面

兩點說明:

1) 視圖集ViewSet中的retrieve名稱,在接口文檔網站中叫作read

2)參數的Description須要在模型類或序列化器類的字段中以help_text選項定義,如:

class Student(models.Model):
    ...
    age = models.IntegerField(default=0, verbose_name='年齡', help_text='年齡')
    ...

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = "__all__"
        extra_kwargs = {
            'age': {
                'required': True,
                'help_text': '年齡'
            }
        }

9.第三方組件Xadmin

xadmin是Django的第三方擴展,比使用Django的admin站點更強大也更方便。

文檔:https://xadmin.readthedocs.io/en/latest/index.html

9.1 安裝與配置

經過以下命令安裝xadmin的最新版

pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2

在配置文件中註冊以下應用

INSTALLED_APPS = [
    ...
    'xadmin',
    'crispy_forms',
    'reversion',
    ...
]
​
# 修改使用中文界面
LANGUAGE_CODE = 'zh-Hans'# 修改時區
TIME_ZONE = 'Asia/Shanghai'

xadmin有創建本身的數據庫模型類,須要進行數據庫遷移

python manage.py makemigrations
python manage.py migrate

在總路由中添加xadmin的路由信息

import xadmin
xadmin.autodiscover()
​
# version模塊自動註冊須要版本控制的 Model
from xadmin.plugins import xversion
xversion.register_models()
​
urlpatterns = [
    path(r'xadmin/', xadmin.site.urls),
]

若是以前沒有建立超級用戶,須要建立,若是有了,則能夠直接使用以前的。

python manage.py createsuperuser

9.2 xadmin的使用

  • xadmin再也不使用Django的admin.py,而是須要編寫代碼在adminx.py文件中。

  • xadmin的站點管理類不用繼承admin.ModelAdmin,而是直接繼承object便可。

例如:在子應用中建立adminx.py文件。

站點的全局配置
import xadmin
from xadmin import views
​
class BaseSetting(object):
    """xadmin的基本配置"""
    enable_themes = True  # 開啓主題切換功能
    use_bootswatch = True
​
xadmin.site.register(views.BaseAdminView, BaseSetting)
​
class GlobalSettings(object):
    """xadmin的全局配置"""
    site_title = "路飛學城"  # 設置站點標題
    site_footer = "路飛學城有限公司"  # 設置站點的頁腳
    menu_style = "accordion"  # 設置菜單摺疊
​
xadmin.site.register(views.CommAdminView, GlobalSettings)
站點Model管理

xadmin可使用的頁面樣式控制基本與Django原生的admin一直。

  • list_display 控制列表展現的字段

    list_display = ['id', 'btitle', 'bread', 'bcomment']

     

  • search_fields 控制能夠經過搜索框搜索的字段名稱,xadmin使用的是模糊查詢

    search_fields = ['id','btitle']

     

  • list_filter 能夠進行過濾操做的列,對於分類、性別、狀態

    list_filter = ['is_delete']

     

  • ordering 默認排序的字段

  • show_detail_fields 在列表頁提供快速顯示詳情信息

  • list_editable 在列表頁能夠快速直接編輯的字段

  • refresh_times 指定列表頁的定時刷新

    refresh_times = [5, 10,30,60]  # 設置容許後端管理人員按多長時間(秒)刷新頁面

     

  • list_export 控制列表頁導出數據的可選格式

    list_export = ('xls', 'xml', 'json')   list_export設置爲None來禁用數據導出功能
    list_export_fields = ('id', 'btitle', 'bpub_date')

     

  • show_bookmarks 控制是否顯示書籤功能

    show_bookmarks = True

     

  • data_charts 控制顯示圖表的樣式

    data_charts = {
            "order_amount": {
              'title': '圖書發佈日期表', 
              "x-field": "bpub_date", 
              "y-field": ('btitle',),
              "order": ('id',)
            },
        #    支持生成多個不一樣的圖表
        #    "order_amount": {
        #      'title': '圖書發佈日期表', 
        #      "x-field": "bpub_date", 
        #      "y-field": ('btitle',),
        #      "order": ('id',)
        #    },
        }
    • title 控制圖標名稱

    • x-field 控制x軸字段

    • y-field 控制y軸字段,能夠是多個值

    • order 控制默認排序

     

  • model_icon 控制菜單的圖標【圖標的設置能夠參考bootstrap的圖標css名稱】

    class BookInfoAdmin(object):
        model_icon = 'fa fa-gift'
    ​
    xadmin.site.register(models.BookInfo, BookInfodmin)

     

  • readonly_fields 在編輯頁面的只讀字段

  • exclude 在編輯頁面隱藏的字段

ok

相關文章
相關標籤/搜索