【DRF】Django REST FramkWork 學習筆記(更新中~)

前言

這篇文章是我從0到1學習 DRF 的學習筆記先把我以爲重要的和踩過的統一記錄下來,後面會單獨拆分紅多篇針對性文章,有什麼不足的,還請你們指正~前端


地址

DRF:www.django-rest-framework.org/
Django:docs.djangoproject.com/zh-hans/2.1…
項目源碼:gitee.com/Actoress/dj…python


切換pip源

豆瓣源:https://pypi.doubanio.com/simple/
  使用豆瓣源安裝:pip3 install -i https://pypi.doubanio.com/simple/ (package_name)
複製代碼

包含的Package

Package Name 功能 備註
django 主開發框架 -
djangorestframework restful風格 基於Django
markdown 支持Markdown djangorestframework須要用到
django-filter filter djangorestframework須要用到
pillow 圖片處理 -

基本命令

建立項目
django-admin startproject (project_name)git

啓動項目
python manage.py runservergithub

啓動項目(指定端口號)
python manage.py runserver 9999web

建立應用
python manage.py startapp (app_name)shell

建立完成後添加應用名到 settings.py 中的 INSTALLED_APPS 配置裏數據庫

校驗項目完整性
checkdjango

進入Django項目的Python Shell環境
shelljson

用例測試
test跨域

建立模型變動的遷移文件(數據庫相關)
makemigrations

執行上一個命令建立的遷移文件(數據庫相關)
migrate

把數據庫數據導出到文件(數據庫相關)
dumpdata

把文件數據導入到數據庫(數據庫相關)
loaddate


項目目錄結構

wsgi.py

WSGI(Python Web Server Gateway Interface)
中文名:Python服務器網關接口
Python應用與Web服務器之間的接口

urls.py

URL配置文件
Django項目中全部地址(頁面)都須要咱們本身去配置其URL

settings.py 最重要的配置文件

配置名 功能 備註
SECRET_KEY Django爲每一個項目自動生成的key
DEBUG 調試模式(生產環境下,絕對別開)
ALLOWED_HOSTS 這個數組裏面全部的地址,都會被屏蔽請求(不能訪問)
INSTALLED_APPS 應用
MIDDLEWARE 中間件(工具集)
ROOT_URLCONF URL的跟文件
TEMPLATES 模板文件
DATABASES 數據庫配置
STATIC_URL 靜態文件地址

應用目錄結構

文件名 功能 備註
migrations 數據遷移模塊
admin.py 該應用的後臺管理系統配置
apps.py 應用配置 1.9之後纔有
models.py 數據模塊,使用ORM框架,相似於MVC結構中的Models
tests.py 自動化測試模塊
views.py 視圖處理文件
urls.py 管理應用路由的地方 需自行建立

virtualenv

新建環境
virtualenv (env_name)

在當前目錄建立虛擬環境,將會生成一個 env_name 的文件夾

啓動虛擬環境
source activate

先 cd 到虛擬環境文件夾的 bin 目錄中,再運行命令

退出虛擬環境
deactivate


Django REST FrameWork 基礎

序列化器類

Serializer

1)若是定義的序列化器類不是針對於模型類,能夠直接繼承此類便可。
2)沒有提供save時的create方法和update方法。

ModelSerializer

1)若是定義的序列化器類是針對於模型類,能夠直接繼承此類便可。
2)提供了save時的create方法和update方法。

1)序列化:

python建立序列化器對象並傳入全部序列化的對象serializer = BookInfoSerializer(book)
獲取序列化以後的字典數據serializer.data

2)反序列化-數據驗證

python建立序列化器對象並傳入數據 serializer = BookInfoSerializer(data=data)
調用is_valid方法進行數據驗證 serializer.is_valid()

3)反序列化-新增或更新

a)新增

python 建立序列化器對象並傳入數據 serializer = BookInfoSerializer(data=data) 調用is_valid方法進行數據驗證 serializer.is_valid() 調用save方法時會調用序列化器類中的create方法,能夠在create方法中實現數據的添加 serializer.save()

b)更新

python 建立序列化器對象並傳入數據 serializer = BookInfoSerializer(book, data=data) 調用is_valid方法進行數據驗證 serializer.is_valid() 調用save方法時會調用序列化器類中的update方法,能夠在update方法中實現數據的添加 serializer.save()

擴展類

類名 說明
ListModelMixin 提供了一個list方法,封裝了返回模型數據列表信息的通用流程。
CreateModelMixin 提供了一個create方法,封裝了建立一條模型對象數據信息的通用流程。
RetrieveModelMixin 提供了一個retrieve方法,封裝了獲取一條模型對象數據信息的通用流程。
UpdateModelMixin 提供了一個update方法,封裝了更新一條模型對象數據信息的通用流程。
DestroyModelMixin 提供了一個destroy方法,封裝了刪除一條模型對象數據信息的通用流程。

子類視圖類

類名 說明
ListAPIView 1)繼承自ListModelMixin和GenericAPIView。2)若是想定義一個視圖只提供列出模型全部信息的接口,繼承此視圖類是最快的方式。
CreateAPIView 1)繼承自CreateModelMixin和GenericAPIView。2)若是想定義一個視圖只提供建立一個模型信息的接口,繼承此視圖類是最快的方式。
RetrieveAPIView 1)繼承自RetrieveModelMixin和GenericAPIView。2)若是想定義一個視圖只提供獲取一個模型信息的接口,繼承此視圖類是最快的方式。
UpdateAPIView 1)繼承自UpdateModelMixin和GenericAPIView。2)若是隻想定義一個視圖只提供更新一個模型信息的接口,繼承此視圖類是最快的方式。
DestroyAPIView 1)繼承自DestroyModelMixin和GenericAPIView。2)若是隻想定義一個視圖只提供刪除一個模型信息的接口,繼承此視圖類是最快的方式。
ListCreateAPIView 1)繼承自ListModelMixin,CreateModelMixin和GenericAPIView。。2)若是隻想定義一個視圖提供列出模型全部建立一個模型信息的接口,繼承此視圖類是最快的方式。
RetrieveUpdateAPIView 1)繼承自RetrieveModelMixin,UpdateModelMixin和GenericAPIView。2)若是隻想定義一個視圖提供獲取一個模型信息更新一個模型信息的接口,繼承此視圖類是最快的方式。
RetrieveUpdateDestoryAPIView 1)繼承自RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin和GenericAPIView。2)若是隻想定義一個視圖提供獲取一個模型信息更新一個模型信息刪除一個模型信息的接口,繼承此視圖類是最快的方式。

視圖集類

類名 說明
ViewSet 1)繼承自ViewSetMixin和APIView。2)若是使用視圖集時不涉及數據庫的操做,能夠直接繼承此類。
GenericViewSet 1)繼承自ViewSetMixin和GenericAPIView。2)若是使用視圖集涉及數據的操做,能夠直接繼承此類。
ModelViewSet 1)繼承自5個Mixin擴展和GenericViewSet。2)若是使用視圖集想一次提供通用的5種操做,繼承這個類是最快的。
ReadOnlyModelViewSet 1)繼承自ListModelMixin,RetrieveModelMixin和GenericViewSet。2)若是使用視圖集想一次提供list操做和retrieve操做,繼承這個類是最快的。

路由Router

1.路由Router是專門配合視圖集來使用的,可使用Router自動生成視圖集中相應處理函數對應的URL配置項。
2.使用Router自動生成視圖集中相應處理函數對應的URL配置項時,除了常見的5種基本操做以外,若是視圖集中有添加的其餘處理方法,則須要給這些方法加上action裝飾器以後,纔會動態生成其對應的URL配置項。


Django REST FrameWork API

Django類視圖(不推薦)

import json
from django.http.response import HttpResponse
from django.views.generic.base import View
from goods.models import Goods

class GoodsListView(View):
    def get(self, request):
        json_list = []
        goods = Goods.objects.all()[:10]
        for good in goods:
            json_dict = {}
            json_dict["name"] = good.name
            json_dict["category"] = good.category.name
            json_list.append(json_dict)
        renturn HttpResponse(json.dumps(json_list), content_type="application/json")
        
------------------------------------------------------------------------------------------
urlpatterns = [
    path('goods/', GoodsListView.as_view(), name="goods"),
]
複製代碼

Django類視圖優化(不推薦)

"""【views.py】"""
import json
from django.http.response import JsonResponse
from django.views.generic.base import View
from django.core import serializers  # 作序列化
from goods.models import Goods

class GoodsListView(View):
    def get(self, request):
        json_list = []
        goods = Goods.objects.all()[:10]
        json_data = serializers("json", goods)  # 作序列化
        json_data = json.loads(json_data)
        return JsonResponse(json_data, safe=False)
        
------------------------------------------------------------------------------------------

"""【urls.py】"""
urlpatterns = [
    path('goods/', GoodsListView.as_view(), name="goods"),
]
複製代碼

Django Rest FrameWork APIView 視圖(推薦)

"""【views.py】"""
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from .models import Goods
from .serializers import GoodsSerializer

class GoodsListView(APIView):
    def get(self, request, format=None):
        goods = Goods.objects.all()[:10]
        serializer = GoodsSerializer(goods, many=True)  # many=True 表示是一個 list 對象
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = GoodsSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        
------------------------------------------------------------------------------------------

"""【serializers.py】"""
from rest_framework import serializers

from .models import Goods

class GoodsSerializer(serializers.Serializer):
    name = serializers.CharField(required=True, max_length=100)
    click_num = serializers.IntegerField(default=0)
    
    def create(self, validated_data):
        """ 重載create方法,當新建一條數據時,會調用這裏的方法,驗證數據 """
        return Goods.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """ Update and return an existing `good` instance, given the validated data. """
        instance.title = validated_data.get('title', instance.title)
        instance.code = validated_data.get('code', instance.code)
        instance.save()
        return instance
        
------------------------------------------------------------------------------------------

"""【urls.py】"""
urlpatterns = [
    path('goods/', GoodsListView.as_view(), name="goods"),
]
複製代碼

Django Rest FrameWork APIView&ModelSerializer 視圖(推薦)

"""【views.py】"""
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from .models import Goods
from .serializers import GoodsSerializer

class GoodsListView(APIView):
    def get(self, request, format=None):
        goods = Goods.objects.all()[:10]
        serializer = GoodsSerializer(goods, many=True)  # many=True 表示是一個 list 對象
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = GoodsSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        
------------------------------------------------------------------------------------------

"""【serializers.py】"""
from rest_framework import serializers

from .models import Goods

class GoodsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Goods
        fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
        # fields = "__all__" # 調用全部字段
        
------------------------------------------------------------------------------------------

"""【urls.py】"""
urlpatterns = [
    path('goods/', GoodsListView.as_view(), name="goods"),
]
複製代碼

Django Rest FrameWork GenericAPIView(推薦)

GenericAPIView: 是對 APIView 的一層封裝

須要重寫 get、post 方法,可從 GenericAPIView 中複製出來修改
若是不寫 get、post 會默認認爲不接受 get、post

字段名 說明
queryset 指定做用的 model 數據範圍
serializer_class 設置 View 的 serializer
lookup_field *
lookup_url_kwarg *
filter_backends *
pagination_class *
可重用的方法 說明
mixins.ListModelMixin get 請求自帶 list 方法
mixins.CreateModelMixin *
mixins.RetrieveModelMixin *
mixins.DestroyModelMixin *
mixins.UpdateModelMixin *
子類視圖 等價於 說明
ListAPIView ListModelMixin + GenericAPIView 提供列出模型全部信息的接口
CreateAPIView CreateModelMixin + GenericAPIView 提供建立一個模型信息的接口
RetrieveAPIView RetrieveModelMixin + GenericAPIView 提供獲取一個模型信息的接口
DestroyAPIView DestroyModelMixin + GenericAPIView 提供刪除一個模型信息的接口
UpdateAPIView UpdateModelMixin + GenericAPIView 提供一個視圖提供列出模型全部和建立一個模型信息的接口
ListCreateAPIView ListModelMixin + CreateModelMixin + GenericAPIView 只提供更新一個模型信息的接口
RetrieveUpdateAPIView RetrieveModelMixin + UpdateModelMixin + GenericAPIView 獲取一個模型信息 更新一個模型信息
RetrieveUpdateDestoryAPIView RetrieveModelMixin + UpdateModelMixin + DestroyModelMixin + GenericAPIView 獲取一個模型信息 更新模型信息 刪除一個模型
"""【views.py】"""
from django.http import Http404
from rest_framework.response import Response
from rest_framework import status
from rest_framework import mixins
from rest_framework import generic
from rest_framework.pagination import PageNumberPagination
from rest_framework.authentication import TokenAuthentication

from .models import Goods
from .serializers import GoodsSerializer

class GoodsPagination(PageNumberPagination):
    """ 商品自定義的分頁 """
    page_size = 20  # 設置單頁的量 前端能夠經過提交 page_size 參數來修改,這裏只是個默認值
    max_page_size = 100  # 設置單頁最大值
    page_size_query_param = 'page_size'  # 自定義每頁數量請求參數
    page_query_param = "p"  # 自定義頁數請求參數

class GoodsListView(mixins.ListModelMixin, generics.GenericAPIView):

    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination  # 調用自定義的分頁
    authentication_classes = (TokenAuthentication, )  # 配置是否須要 token
    
    def get(self, request, format=None):
        goods = Goods.objects.all()[:10]
        serializer = GoodsSerializer(goods, many=True)  # many=True 表示是一個 list 對象
        return Response(serializer.data)
        
------------------------------------------------------------------------------------------

"""【serializers.py】"""
from rest_framework import serializers

from .models import Goods

class GoodsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Goods
        fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
        # fields = "__all__" # 調用全部字段
        
------------------------------------------------------------------------------------------

"""【urls.py】"""
urlpatterns = [
    path('goods/', GoodsListView.as_view(), name="goods"),
]
複製代碼

Django Rest FrameWork GenericAPIView(推薦)

"""【views.py】"""
from rest_framework import mixins
from rest_framework import viewsets
from rest_framework.pagination import PageNumberPagination
from rest_framework.authentication import TokenAuthentication

from .models import Goods
from .serializers import GoodsSerializer

class GoodsPagination(PageNumberPagination):
    """ 商品自定義的分頁 """
    page_size = 20  # 設置單頁的量 前端能夠經過提交 page_size 參數來修改,這裏只是個默認值
    max_page_size = 100  # 設置單頁最大值
    page_size_query_param = 'page_size'  # 自定義每頁數量請求參數
    page_query_param = "p"  # 自定義頁數請求參數

class GoodsListView(mixins.ListModelMixin, viewsets.GenericViewSet):

    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination  # 調用自定義的分頁
        
------------------------------------------------------------------------------------------

"""【serializers.py】"""
from rest_framework import serializers

from .models import Goods

class GoodsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Goods
        fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
        # fields = "__all__" # 調用全部字段
        
------------------------------------------------------------------------------------------

"""【urls.py】"""
# 不使用 router 的配置
from goods.views import GoodsListViewSet

goods_list = GoodsListViewSet.as_view({
    'get': 'list',  # 將 get 請求綁定到 list() 上
    'post': 'create',  # 將 post 請求綁定到 create() 上
})

urlpatterns = [
    path('goods/', GoodsListView.as_view(), name="goods"),
]
複製代碼

Django REST FrameWork跨域

github.com/ottoyiu/dja…


Django REST FrameWork JWT

JWT: json web token

地址:github.com/GetBlimp/dj…

token結構 (帳號密碼base64).(簽名)


DRF 的 Request 和 Response

DRF 對 Django 原生的 Request 和 Response作了一層封裝,給咱們的使用帶來了更大的便利

Request

request.data

返回請求正文的已解析內容,GET和POST都同樣

  • 它包括全部已解析的內容,包括文件和非文件輸入。
  • 它支持解析除HTTP方法以外的其餘內容POST,這意味着您能夠訪問內容PUT和PATCH請求。
  • 它支持REST框架的靈活請求解析,而不單單支持表單數據。例如,您能夠像處理傳入表單數據同樣處理傳入的JSON數據

request.query_params

裏面放有請求頭傳遞過來的參數
不止是GET的請求頭,POST PUT DELETE的請求頭都會在這裏面
建議使用request.query_params而不是Django的標準request.GET

request.parsers

內容解析的 parser
一般不須要訪問此屬性

request.user

獲取當前的用戶

requset.auth

一般不須要訪問此屬性

Responses

支持各類類型的返回

  • data: 返回的數據
  • status: 狀態碼,默認是200
    • template_name: 返回 template
  • headers: http headers
  • content_type: http content_type
相關文章
相關標籤/搜索