這篇文章是我從0到1學習 DRF 的學習筆記先把我以爲重要的和踩過的統一記錄下來,後面會單獨拆分紅多篇針對性文章,有什麼不足的,還請你們指正~前端
DRF:www.django-rest-framework.org/
Django:docs.djangoproject.com/zh-hans/2.1…
項目源碼:gitee.com/Actoress/dj…python
豆瓣源:https://pypi.doubanio.com/simple/
使用豆瓣源安裝:pip3 install -i https://pypi.doubanio.com/simple/ (package_name)
複製代碼
Package Name | 功能 | 備註 |
---|---|---|
django | 主開發框架 | - |
djangorestframework | restful風格 | 基於Django |
markdown | 支持Markdown | djangorestframework須要用到 |
django-filter | filter | djangorestframework須要用到 |
pillow | 圖片處理 | - |
建立項目
django-admin startproject (project_name)
git
啓動項目
python manage.py runserver
github
啓動項目(指定端口號)
python manage.py runserver 9999
web
建立應用
python manage.py startapp (app_name)
shell
建立完成後添加應用名到 settings.py 中的 INSTALLED_APPS 配置裏數據庫
校驗項目完整性
check
django
進入Django項目的Python Shell環境
shell
json
用例測試
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 (env_name)
在當前目錄建立虛擬環境,將會生成一個 env_name 的文件夾
啓動虛擬環境
source activate
先 cd 到虛擬環境文件夾的 bin 目錄中,再運行命令
退出虛擬環境
deactivate
1)若是定義的序列化器類不是針對於模型類,能夠直接繼承此類便可。
2)沒有提供save時的create方法和update方法。
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操做,繼承這個類是最快的。 |
1.路由Router是專門配合視圖集來使用的,可使用Router自動生成視圖集中相應處理函數對應的URL配置項。
2.使用Router自動生成視圖集中相應處理函數對應的URL配置項時,除了常見的5種基本操做以外,若是視圖集中有添加的其餘處理方法,則須要給這些方法加上action裝飾器以後,纔會動態生成其對應的URL配置項。
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"),
]
複製代碼
"""【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"),
]
複製代碼
"""【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"),
]
複製代碼
"""【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"),
]
複製代碼
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"),
]
複製代碼
"""【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"),
]
複製代碼
JWT: json web token
token結構 (帳號密碼base64).(簽名)
DRF 對 Django 原生的 Request 和 Response作了一層封裝,給咱們的使用帶來了更大的便利
返回請求正文的已解析內容,GET和POST都同樣
裏面放有請求頭傳遞過來的參數
不止是GET的請求頭,POST PUT DELETE的請求頭都會在這裏面
建議使用request.query_params而不是Django的標準request.GET
內容解析的 parser
一般不須要訪問此屬性
獲取當前的用戶
一般不須要訪問此屬性
支持各類類型的返回