setting

 

admin

登錄功能,因此咱們使用django內置admin站點並建立一個管理員.css

python manage.py createsuperuser

建立管理員之後,訪問admin站點,先修改站點的語言配置html

setting前端

LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True

 

認證Authentication

能夠在配置文件settings.py,中配置全局默認的認證方案python

寫入git

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

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

from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.views import APIView

class ExampleView(APIView):
    # 類屬性
    authentication_classes = [SessionAuthentication, BasicAuthentication]
    ...

認證失敗會有兩種可能的返回值:數據庫

  • 401 Unauthorized 未認證django

  • 403 Permission Denied 權限被禁止json

 

權限Permissions

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

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

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

 

全局配置


權限
全局,針對整個站點的全部視圖進行權限的判斷 
針對內部系統,每每纔會使用到全局的權限判斷,這時候,針對容許遊客均可以訪問的頁面,針對外部系統,大部分頁面都是容許遊客訪問的,就不要進行全局配置了

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

settings

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

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

'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,)
    ...
(IsAuthenticated,)是元組,也可用列表

提供的權限

  • AllowAny 容許全部用戶

  • IsAuthenticated 僅經過認證的用戶

  • IsAdminUser 僅管理員用戶

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

 

自定義權限

如需自定義權限,需繼承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 CustomerPermission(BasePermission):
    def has_permission(self, request, view):
        if request.user.username != "root":
            return False

        if request.query_params.get("password") == "123456":
            return True
        else:
            return False

views

from rest_framework.views import APIView
from rest_framework.response import Response
from .permissions import CustomerPermission
class StudentAPIView(APIView):
    permission_classes = [CustomerPermission]

    def get(self,request):
        """獲取學生信息"""
        return Response({"message":"ok"})

 

 

限流Throttling

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

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

能夠在配置文件中,使用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, hour或day來指明週期。

from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
class StudentAPIView(APIView):
    throttle_classes = [UserRateThrottle]
    def get(self,request):
        return Response({"message":"ok"})

 

可選限流類

1) AnonRateThrottle

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

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

2)UserRateThrottle

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

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

3)ScopedRateThrottle

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

例如:

settings

'rest_framework.throttling.ScopedRateThrottle',  自定義視圖
'books': '2/minute'
REST_FRAMEWORK = {
    # 限流
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.ScopedRateThrottle',  # 針對自定義視圖。進行限流
    ),
    # 全局配置,針對整個項目中全部的視圖進行限流
    'DEFAULT_THROTTLE_RATES': {
        'books': '2/minute',   # 'books'要與views中的名字相同
    }
}

 

views

throttle_scope = 'books'
from rest_framework.views import APIView
from rest_framework.response import Response
class StudentAPIView(APIView):
    throttle_scope = 'books'   # throttle_scope 變量名固定寫法  'books'要和setting中名字相同
  def get(self,request): 
    return Response({"message":"ok"})

 

過濾Filtering

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

pip install django-filter

 

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

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

REST_FRAMEWORK = {
    ...
  # 數據過濾
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

 

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

from rest_framework.generics import ListAPIView
from students.models import Student
from students.serializers import StudentModelSerializer
class StudentListAPIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_fields =['name']  # 查詢name,條件寫在url上,以下
# 127.0.0.1:8000/four/students/?name=條件

 

排序

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

使用方法:

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

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

-id 表示針對id字段進行倒序排序
id 表示針對id字段進行升序排序

導入

from rest_framework.filters import OrderingFilter
from rest_framework.generics import ListAPIView
from students.models import Student
from students.serializers import StudentModelSerializer
from rest_framework.filters import OrderingFilter      # 排序
class StudentListAPIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [OrderingFilter]          # 使用過濾器filter_backends 
   ordering_fields = ["id","age"]                    # 已id或age排序
# url訪問以下
# http://127.0.0.1:8000/home/students1/?ordering=-id

 

可是若是想篩選排序須要增長

若是須要在過濾之後再次進行排序,則須要二者結合!必須在視圖中的filter_backends下增長過濾器的類聲明

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.generics import ListAPIView
from students.models import Student
from students.serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend     # 篩選
from rest_framework.filters import OrderingFilter                  # 排序
class StudentListAPIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [OrderingFilter,DjangoFilterBackend]     # 加入篩選DjangoFilterBackend
    ordering_fields= ["id","age"]                  # 已id多age排序
    filter_fields = ['name']                               # 已name篩選
# url訪問以下
# http://127.0.0.1:8000/home/students1/?name=小藍&ordering=-id

 

若是排序時,須要針對多個字段進行排序,則可使用第二排序

http://127.0.0.1:8000/home/student_list/?ordering=-age,-id
# 當age的值都一致的時候,使用id針對這些數據進行倒敘

 

 

分頁Pagination

 REST framework提供了分頁的支持

全局配置

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

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

在views中  
pagination_class = None # 能夠取消分頁的影響

 

局部配置

 也可經過自定義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

 

 

可選分頁器

1) PageNumberPagination

前端訪問網址形式:

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

  • page_size 每頁數目

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

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

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

建立一個pagination.py文件,用來寫分頁
# 建立一個pagination.py文件,用來寫分頁
from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination
class StudentPagination(PageNumberPagination):
    page_query_param = "page"  # 分頁頁碼的參數名稱

    page_size_query_param = "page_size" # 單頁數據量的參數名稱
    max_page_size = 10  # 設置容許客戶端修改每一頁顯示數據量的多少
    page_size = 3       # 默認狀況下,一頁顯示的數據量多少

 

views

from .pagination import StudentPagination
class StudentListAPIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    pagination_class = StudentPagination  # 分頁導入

 

2)LimitOffsetPagination

前端訪問網址形式:

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

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

  • 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

 

異常處理 Exceptions

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

在項目下建立utils文件execptions.py

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

 

 

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

在項目下建立utils文件execptions.py建立一個叫custom_exception_handler的函數

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': '項目名.utils.execptions.custom_exception_handler'
}

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

settings

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}

 

例如:

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

from rest_framework.views import exception_handler
from django.db import DatabaseError  # 導入數據庫異常
from rest_framework.response import Response
from rest_framework import status
def customer_execptions(exc, context):
    """自定義異常"""
    # 優先調用drf自己的異常處理,它的返回值要麼是None,要麼是response
    response = exception_handler(exc, context)

    if response is None:
        # 判斷是不是數據庫
        if isinstance(exc, DatabaseError):
            view = context['view']
            print( '[%s]: %s' % (view, exc) )
            response = Response(data={"msg":"服務器內部存儲錯誤!請聯繫網站客服管理員!"}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

    return response

 

REST framework預約義的異常類

 

  • APIException 全部api異常的父類

  • ParseError 解析錯誤

  • AuthenticationFailed 認證失敗

  • NotAuthenticated 還沒有認證

  • PermissionDenied 權限拒絕

  • NotFound 404未找到

  • MethodNotAllowed 請求方式不支持

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

  • Throttled 超過限流次數

  • ValidationError 校驗失敗

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

 

自動生成接口文檔

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

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

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

 

騰訊api開放平臺

 https://wiki.open.qq.com/wiki/API%E5%88%97%E8%A1%A8

 

安裝依賴

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

pip install coreapi

在drf的配置增長配置項:

REST_FRAMEWORK = {
    # 加載文檔聲明
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema',
}

 

設置接口文檔訪問路徑

 

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

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

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

 

from rest_framework.documentation import include_docs_urls
urlpatterns = [
    ...
    path('docs/', include_docs_urls(title='站點頁面標題',description="詳細描述"))
 ]

 

文檔描述說明的定義位置

 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': '年齡'
            }
        }

 

Xadmin

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

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

安裝

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

pip install django.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

使用

  • 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 在編輯頁面隱藏的字段

 

實例

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)

from .models import Student
class StudentAdmin(object):
    list_display = ["id","name","sex","age","class_null"]
    search_fields = ["name","age","class_null"]
    list_filter = ["sex","age"]
    ordering = ["id","class_null"]
    show_detail_fields = ["name"]
    list_editable = ["age"]
    refresh_times = [5, 10, 30, 60]

    data_charts = {
        "members": {
            'title': '會員的年齡分佈',
            "x-field": "age",
            "y-field": ('id',),
            "order": ('age',)
        },
        #    支持生成多個不一樣的圖表
        #    "order_amount": {
        #      'title': '圖書發佈日期表',
        #      "x-field": "bpub_date",
        #      "y-field": ('btitle',),
        #      "order": ('id',)
        #    },
    }

    model_icon = 'fa fa-star'


xadmin.site.register(Student, StudentAdmin)
View Code
相關文章
相關標籤/搜索