restful framework 风格写法
参考资料
cbv resfull写法
from django.utils.decorators import method_decorator
# 忽略csrf请求
class ...():
@method_decorator(csrf_exempt)
def dispatch(...):
return super(...,self).dispatch(...)
def ...():
def ...():
def ...():
def ...():
或者
@method_decorator(csrf_exempt, name='dispatch')
class ...():
def ...():
def ...():
def ...():
序列化问题
class xxxxserializers(serializers.Serializer):
xxx = serializers.CharField(source='数据库字段') # 外键可以使用.语法
# 自定义显示
xxx = serializers.SerializerMythodField()
def get_xxx(self,row):
xxx_obj_list = row.xxx.all()
ret = []
for item in xxx_obj_list:
ret.append({'id':item.id, 'title':item.title, ...})
return ret
# ModelSerializer继承于Serializer 推荐继承这个
class xxxxserializers(serializers.ModelSerializer):
xxx = serializers.CharField(source='数据库字段') # 外键可以使用.语法
xxx = serializers.SerializerMethodField() # 自定义显示
class Meta:
models = '数据表'
# 可以混合使用
fields = ['字段','xxx','xxx'] # '__all__' 所有字段
# 数据库层级控制(序列化链表操作)
depth = 1
def get_xxx(self,row):
xxx_obj_list = row.xxx.all()
ret = []
for item in xxx_obj_list:
ret.append({'id':item.id, 'title':item.title, ...})
return ret
# 定制类
class MyField(serializers.CharField):
# 重写返回的数据
def to_representation(self, value):
方法...
return 'xxx'
class xxxxserializers(serializers.ModelSerializer):
# 绑定url上的反向name,可以显示出完整路由
group = serializers.HyperlinkedIdentityField(view_name='xxx',lookup_field='group_id',lookup_url_kwarg='url尾部上的参数')
序列化器的验证功能
class xxxxserializers(serializers.Serializer):
# 验证使用is_valid()
xxx = serializers.CharField(error_messages={'required': '数据为空时返回'})
# 自定义验证规则
xxx = serializers.CharField(error_messages={'required': '数据为空时返回'}, validators=[验证函数(),])
分页
方法一
class xxxxserializers(serializers.ModelSerializer):
class Meta:
models = '数据表'
fields = '__all__'
views:
from rest_framework.pagination import PageNumberPagination
class Page1Views(APIView)
def get(self, request, *arg, *kwargs):
# 实例化数据表对象
user = User.objects.all()
# 实例化分页器
page = PageNumberPagination()
# 在settings内配置 "PAGE_SIZE" = 数据量 请求时 ?page=n页
# &page_size=数据量
# 进行分页 三个参数 数据 请求 视图
page_user = page.paginate_queryset(queryset=user, request=request, view = self)
# 进行序列化
ser = pageSerialiser(instance=page_user, many=Ture)
# 路由?page=n页
# restful内部封装的response,自带翻页器 推荐使用
return page.get_paginated_response(ser.data)
# 传统返回
return Response(ser.data)
# 自定义分页器 继承pageSerialiser重写里面的方法
class MypageSerialiser(pageSerialiser):
# 自定义显示数据
page_size = 10 # 每页的数据量
# 定制每页数据量 取值方法 &page_size=数据量
page_size_query_param = None # 可以修改显示数据量 默认是None
# 定制每页最大取值数据量
max_page_size = 5 # 通过&page_size方法最大取值为5
# 显示页码key
page_query_param = 'page'
方法二
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination
class Page1Views(APIView)
def get(self, request, *arg, *kwargs):
user = User.objects.all()
# 取值方法?offset = 0 从来开始分页 &limit = 3 向后取的数据数量
page = LimitOffsetPagination()
# 自定义分页器 LimitOffsetPagination重写里面的方法
class MyLimitOffsetPagination(LimitOffsetPagination):
default_limit = 2 # 默认的页面数据数量
limit_query_param = 'limit' # 定制取数据页码key ?
offset_query_param = 'offset' # 默认取数据页码key &
max_limit = 5 # 数据每页取值的最大上限
方法三(加密分页)
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
class Page1Views(APIView)
def get(self, request, *arg, *kwargs):
user = User.objects.all()
# 取值方法?cursor = 页码非数字,而是被加密后随机字符串
page = CursorPagination()
# 自定义分页器 CursorPagination重写里面的方法
class MyCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 定制取数据页码key ?
page_size = 10 # 每页的数据量
ordering = '-id' # 排序规则,可以正负
# 定制每页数据量 取值方法 &page_size=数据量
page_size_query_param = None # 可以修改显示数据量 默认是None
max_page_size = 5 # 最大取值为5
视图继承
(view—APIView—GenericAPIView—GenericViewSet—ModelViewSet)
### GenericAPIView
from rest_framework.generics impost GenericAPIView
class Page1Views(GenericAPIView)
queryset = models.User.objects.all() # 指定数据表
serializer_class = PageNumberPagination # 指定序列化类
pagination_class = PageNumberPagination # 指定分页类
def get(self, request, *arg, *kwargs):
user = self.get_queryset() # 拿到指定数据表
page_user = self.paginate_queryset(user) # 拿到分页结果
ser = self.get_serializer(instance=page_user, many=True)
return Response(ser.data)
### GenericViewSet
from rest_framework.viewsets impost GenericViewSet
from rest_framework.mixins impost ListModelMixin , CreateModelMixin
class Page1Views(ListModelMixin, CreateModelMixin, GenericViewSet) # 多继承 ListModelMixin 将数据列表化 CreateModelMixin 给用户post接口 直接添加保存数据
# url url(r'^api/user/$', views.Page1Views.as_view({'get':'xxx', 'post': 'xxx',...}))
def xxx(self, request, *arg, *kwargs):
# 将路由请求变化
### ModelViewSet
from rest_framework.viewsets impost ModelViewSet
# url 完成CRUD全部功能
url(r'^api/user/$', views.Page1Views.as_view({'get':'retrieve', 'delete': 'destroy', 'put': 'update', 'patch': 'partial_update'}))
class Page1Views(ModelViewSet)
queryset = models.User.objects.all() # 指定数据表
serializer_class = PageNumberPagination # 指定序列化类
pagination_class = PageNumberPagination # 指定分页类
路由渲染器
# 自动生成url
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'xxxx', views.Viewview)
url(r'^',include(router.urls))
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer, AdminRenderer, HTMLFormRenderer
class Page1Views(APIView)
# 自定义数据返回视图
renderer_classes = [JSONRenderer, BrowsableAPIRenderer, AdminRenderer]
def get(self, request, *arg, *kwargs):
user = User.objects.all()
page = LimitOffsetPagination()