drf ( 學習第四部 )
目錄
分頁Pagination
安裝依賴
設定介面文件訪問路徑
訪問介面文件網頁
列表頁配置
詳情頁配置
安裝
站點的全域性配置
DRF框架中常用的元件
分頁Pagination
REST framework 提供了分頁的支援. 我們可以在配置檔案中設定全域性的分頁方式,如:
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 100 # 每頁數目 }
如果在配置settings.py檔案中, 設定了全域性分頁,那麼在drf中凡是呼叫了ListModelMixin的list(),都會自動分頁。如果專案中出現大量需要分頁的資料,只有少數部分介面不需要分頁,則可以在少部分的檢視類中關閉分頁功能。
class 檢視類(ListAPIView): pagination_class = None
也可以通過自定義P阿覅nation類 ,來為檢視新增不同分頁行為. 在檢視中通過 pagination_class屬性來指明.
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
可選分頁器
! ) PagiNumberPagination
前端訪問網址形式:
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 ) LinitOffsetPagination
前端訪問網址形式:
GET http://127.0.0.1/four/students/?limit=100&offset=100
可以在子類中定義的屬性:
default預設限制, 預設值與 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
異常處理Exceptions
REST framework 提供了自定義異常處理, 我們可以自定義的方式來編寫異常處理函式. 例如我們想要在要建立一個自定義異常函式.
這個函式, 我們儲存到當前主應用中( 注意在實際工作中, 我們可以設定一個單獨的獨立的公共目錄來儲存這種公共的函式/工具/類庫 ) .
drfemo/exceptions.py, 程式碼:
"""自定義異常""" # drf內建的異常處理,僅僅針對於API介面進行異常處理,不是api出錯,則不識別,不處理 from rest_framework.views import exception_handler as drf_exception_handler from django.db import DatabaseError from rest_framework.response import Response from rest_framework import status from django.core.exceptions import ImproperlyConfigured def custom_exception_handler(exc,context): """ 自定義異常處理函式 :param exc: 異常物件,本次發生的異常物件 :param context: 字典,異常出現時的執行上下文環境 :return: """ # 返回值要麼是報錯的響應資訊,要麼就是None response = drf_exception_handler(exc,context) if response is None: if isinstance(exc, DatabaseError): # 資料庫異常 # 一般先進行日誌的記錄 # 然後才返回給客戶端 response = Response({"detail":"資料庫異常"}, status=status.HTTP_507_INSUFFICIENT_STORAGE) # 其他的異常處理 if isinstance(exc, Exception): response = Response({"detail":"資料訪問出錯"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return response
在主應用的配置檔案settings.py 中宣告自定義的異常處理
REST_FRAMEWORK = { # 異常處理 'EXCEPTION_HANDLER': 'drfdemo.exceptions.custom_exception_handler', }
如果未宣告, 會採用預設的方式, 如下:
rest_framework/settings.py
REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler' }
REST framework 定義的異常
- ParseError 解析錯誤
- AuthenticationFailed 認證失敗
- NotAuthenticated 尚未認證
- PermissionDenied 許可權受限
- NotFound 未找到
- MethodNotAllowed 請求方式不支援
- NotAcceptable 要獲取的資料格式不支援
- Throttled 超過限流次數
- ValidationError 校驗失敗
也就是說, 很多的沒有在上面列出來的異常,就需要我們在自定義異常中子處理了.
自動生成介面文件
REST framework可以自動幫助我們生成介面文件。
介面文件以網頁的方式呈現。
自動介面文件能生成的是繼承自APIView
及其子類的檢視。
安裝依賴
REST framework 生成介面文件需要 core挨批 庫的支援
pip install coreapi
設定介面文件訪問路徑
在settings.py中配置介面文件
REST_FRAMEWORK = { # 。。。 其他選項 # 介面文件 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema', }
在總路由中新增介面文件路徑.
文件路由對應的檢視配置為:
引數title 為介面文件網站的標題.
from rest_framework.documentation import include_docs_urls urlpatterns = [ ... path('docs/', include_docs_urls(title='站點頁面標題')) ]
文件描述說明的定義位置
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: 修改圖書的閱讀量 """
訪問介面文件網頁
瀏覽器訪問 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': '年齡' } }
Admin
django內建了一個強大的元件叫Admin, 提供給網站管理員快速開發運營後臺的管理站點.
站點文件:
輔助文件:https://www.runoob.com/django/django-admin-manage-tool.html
注意:要使用Admin,必須先建立超級管理員. python manage.py createsuperuser
訪問地址:
admin 站點預設並沒有提供其他的操作給我們,所以一切功能都需要我們進行配置, 在專案中,我們每次建立子應用的時候都會存在一個admin,朋友檔案. 這個檔案就是用於配置admin站點功能的檔案.
admin, py 裡面允許我們編寫的程式碼一共可以分成2部分:
列表頁配置
主要用於針對專案中各個子應用裡面的model.py裡面的模型, 根據這些模型自動生成後臺運營站點的管理功能.
from django.contrib import admin from .models import Student class StudentModelAdmin(admin.ModelAdmin): """學生模型管理類""" pass # admin.site.register(模型類, 模型管理類) admin.site.register(Student, StudentModelAdmin)
關於列表的配置嗎程式碼:
from django.contrib import admin from .models import Student class StudentModelAdmin(admin.ModelAdmin): """學生模型管理類""" date_hierarchy = 'born' # 按指定時間欄位的不同值來進行選項排列 list_display = ['id', "name", "sex", "age", "class_num","born","my_born"] # 設定列表頁的展示欄位 ordering = ['-id'] # 設定預設排序欄位,欄位前面加上-號表示倒敘排列 actions_on_bottom = True # 下方控制欄是否顯示,預設False表示隱藏 actions_on_top = True # 上方控制欄是否顯示,預設False表示隱藏 list_filter = ["class_num"] # 過濾器,按指定欄位的不同值來進行展示 search_fields = ["name"] # 搜尋內容 def my_born(self,obj): return str(obj.born).split(" ")[0] my_born.short_description = "出生日期" # 自定義欄位的描述資訊 my_born.admin_order_field = "born" # 自定義欄位點選時使用哪個欄位作為排序條件 # admin.site.register(模型類, 模型管理類) admin.site.register(Student, StudentModelAdmin)
詳情頁配置
from django.contrib import admin from .models import Student class StudentModelAdmin(admin.ModelAdmin): """學生模型管理類""" date_hierarchy = 'born' # 按指定時間欄位的不同值來進行選項排列 list_display = ['id', "name", "sex", "age", "class_null","born","my_born"] # 設定列表頁的展示欄位 ordering = ['-id'] # 設定預設排序欄位,欄位前面加上-號表示倒敘排列 actions_on_bottom = True # 下方控制欄是否顯示,預設False表示隱藏 actions_on_top = True # 上方控制欄是否顯示,預設False表示隱藏 list_filter = ["class_null"] # 過濾器,按指定欄位的不同值來進行展示 search_fields = ["name"] # 搜尋內容 def my_born(self,obj): return str(obj.born).split(" ")[0] my_born.short_description = "出生日期" # 自定義欄位的描述資訊 my_born.admin_order_field = "born" # 自定義欄位點選時使用哪個欄位作為排序條件 def delete_model(self, request, obj): """當站點刪除當前模型時執行的鉤子方法""" print("有人刪除了模型資訊[新增/修改]") # raise Exception("無法刪除") # 阻止刪除 return super().delete_model(request, obj) # 繼續刪除 def save_model(self, request, obj, form, change): """ 當站點儲存當前模型時 """ print("有人修改了模型資訊[新增/修改]") # 區分新增和修改? obj是否有id print(obj.id) return super().save_model(request, obj, form, change) # fields = ('name', 'age', 'class_null', "description") # exclude 作用與fields相反 # readonly_fields = ["name"] # 設定只讀欄位 # 欄位集,fieldsets和fields只能使用其中之一 fieldsets = ( ("必填項", { 'fields': ('name', 'age', 'sex') }), ('可選項', { 'classes': ('collapse',), # 摺疊樣式 'fields': ('class_null', 'description'), }), ) # admin.site.register(模型類, 模型管理類) admin.site.register(Student, StudentModelAdmin)
Xadmin
下點敏是Django 的第三方擴充套件, 是一個比Django的admin站點使用更方便的後臺站點,.構建於admin站點之上.
文件:http://sshwsfc.github.io/xadmin/
安裝
通過如下命令安裝xadmin的最新版
pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2
在配置檔案settings.py中註冊如下應用:
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('xadmin/', xadmin.site.urls), ]
建立超級使用者
python manage.py createsuperuser
使用
- xadmin不用使用Django的admin.py 進行功能配置樂樂, 而是需要編寫程式碼在admin.py檔案中.
- xadmin的站點管理類不用繼承 admin.ModelAdmin, 而是直接繼承 object 即可
例如: 在子應用 students 中建立 admin.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', 'title', 'read', 'comment']
-
- search_fields控制可以通過搜尋框搜尋的欄位名稱, xadmin使用的是模糊查詢
-
search_fields = ['id','title']
-
- list_filter 可以進行過濾操作的列, 對於分類, 性別,狀態
-
list_filter = ['is_delete']
-
- ordering預設排序的欄位
- readonly_fields在編輯頁面的只讀欄位
- exclude 在編輯頁面隱藏的欄位
- list_editable 在列表頁可以快速直接編寫的欄位
- show_detail_fields 在列表頁提供快速顯示詳情資訊
- refresh_times 指定列表頁的定時重新整理
-
refresh_times = [5, 10,30,60] # 設定允許後端管理人員按多長時間(秒)重新整理頁面
-
- list_export 控制列表匯出資料的可選格式
-
list_export = ('xls', 'xml', 'json') list_export設定為None來禁用資料匯出功能 list_export_fields = ('id', 'title', 'pub_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 控制選單的圖示
這裡使用的圖示是來自 bootstrap3 的圖示.
class BookInfoAdmin(object): model_icon = 'fa fa-gift' xadmin.site.register(models.BookInfo, BookInfodmin)
修改admin或者下低敏站點下的子應用成中文內容.
# 在子應用的apps.py下面的配置中,新增一個屬性verbose_name from django.apps import AppConfig class StudentsConfig(AppConfig): name = 'students' verbose_name = "學生管理" # 然後在當前子應用的__init__.py裡面新增一下程式碼: default_app_config = "students.apps.StudentsConfig"