前言
这篇文章是我从0到1学习 DRF 的学习笔记先把我觉得重要的和踩过的统一记录下来,后面会单独拆分成多篇针对性文章,有什么不足的,还请大家指正~
地址
DRF:www.django-rest-framework.org/
Django:docs.djangoproject.com/zh-hans/2.1…
项目源码:gitee.com/Actoress/dj…
Django 基础
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()
路由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 generics
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跨域
DRF 的 Request 和 Response
View APIView Viewset
过滤
用户登录注册及JWT
自动生成API文档相关
www.django-rest-framework.org/topics/docu…