其他功能元件 LL

朱饱饱發表於2024-03-13
default_limit 預設限制,預設值與PAGE_SIZE設定一直
limit_query_param limit引數名,預設'limit'
offset_query_param offset引數名,預設'offset'
max_limit 最大limit限制,預設None

1、過濾Filtering

對於列表資料可能需要根據欄位進行過濾,我們可以透過新增django-fitlter擴充套件來增強支援。

pip install django-filter

在配置檔案中增加過濾後端的設定:

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

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

在檢視中新增filter_fields屬性,指定可以過濾的欄位

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    filter_fields = ('btitle', 'bread')

# 127.0.0.1:8000/books/?btitle=西遊記

2、排序

對於列表資料,REST framework提供了OrderingFilter過濾器來幫助我們快速指明資料按照指定欄位進行排序。

使用方法:

在類檢視中設定filter_backends,使用rest_framework.filters.OrderingFilter過濾器,REST framework會在請求的查詢字串引數中檢查是否包含了ordering引數,如果包含了ordering引數,則按照ordering引數指明的排序欄位對資料集進行排序。

前端可以傳遞的ordering引數的可選欄位值需要在ordering_fields中指明。

示例:

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = ('id', 'bread', 'bpub_date')

# 127.0.0.1:8000/books/?ordering=-bread

3、分頁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

4、可選分頁器

1) PageNumberPagination

前端訪問網址形式:

GET  http://api.example.org/books/?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_query_param = 'page_size'
    max_page_size = 10

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all().order_by('id')
    serializer_class = BookInfoSerializer
    pagination_class = StandardPageNumberPagination

# 127.0.0.1/books/?page=1&page_size=2

2)LimitOffsetPagination

前端訪問網址形式:

GET http://api.example.org/books/?limit=100&offset=400

可以在子類中定義的屬性:

from rest_framework.pagination import LimitOffsetPagination

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all().order_by('id')
    serializer_class = BookInfoSerializer
    pagination_class = LimitOffsetPagination

# 127.0.0.1:8000/books/?offset=3&limit=2

5、異常處理 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 not None:
        response.data['status_code'] = response.status_code

    return response

在配置檔案中宣告自定義的異常處理

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

如果未宣告,會採用預設的方式,如下

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 校驗失敗

6、自動生成介面文件

REST framework可以自動幫助我們生成介面文件。

介面文件以網頁的方式呈現。

自動介面文件能生成的是繼承自APIView及其子類的檢視。

安裝依賴

REST framewrok生成介面文件需要coreapi庫的支援。

pip install coreapi

設定介面文件訪問路徑

在總路由中新增介面文件路徑。

文件路由對應的檢視配置為rest_framework.documentation.include_docs_urls

引數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:
    修改圖書的閱讀量
    """

訪問介面文件網頁

兩點說明:

1) 檢視集ViewSet中的retrieve名稱,在介面文件網站中叫做read

2)引數的Description需要在模型類或序列化器類的欄位中以help_text選項定義,如:

class BookInfo(models.Model):
    ...
    bread = models.IntegerField(default=0, verbose_name='閱讀量', help_text='閱讀量')
    ...
或

class BookReadSerializer(serializers.ModelSerializer):
    class Meta:
        model = BookInfo
        fields = ('bread', )
        extra_kwargs = {
            'bread': {
                'required': True,
                'help_text': '閱讀量'
            }
        }

7、Xadmin

xadmin是Django的第三方擴充套件,可是使Django的admin站點使用更方便。

文件:

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

安裝

透過如下命令安裝xadmin的最新版

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

在配置檔案中註冊如下應用

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 把apps目錄設定環境變數中的導包路徑
sys.path.append( os.path.join(BASE_DIR,"luffy/apps") )


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

使用

  • 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 預設排序的欄位

  • 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', '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 控制選單的圖示

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

相關文章