标签:取数 books 写视图 ram 根据 自带 only ext model
零,DRF框架预备知识
APIView与View的区别
APIView继承了View
csrf的豁免
重现封装request对象
原生的request赋值给了request._request
request.query_params封装了原生的request.GET
request.data封装了除GET外的所有信息(request.POST,request.files)
响应对象Response
携带HTTP表中状态码
做模板的渲染
一,restful规范
REST风格
表述状态转移:web交换方案,前后端的数据传输的设计思想
资源的概念:在web中只要又被引用的必要都是资源
URI
URI:同一资源标识符
URL:统一资源定位符,URI的子集
统一资源接口
根据HTTP请求方式的不同对资源进行不同的操作
遵循HTTP请求的语义
资源的表述
前后端的传输叫资源的表述
传输的不是资源的本身,而是资源的某一种表述形式
资源的状态
前端展示的叫资源的状态
通过超链接的指引告诉用户接下来有哪些资源状态可以进入
核心思想
面向资源编程
每个url就是资源的体现,不体现操作,url命名尽量用名词不要用动词
根据HTTP请求方式的不同对资源进行不同的操作
URL体现:
版本
htttps://v1.xxx.com
https://xxx.com/v3
体现是否为API接口
https://v1.xxx.com/api
过滤信息
https://v1.xxx.com?page=1
尽量使用HTTPS
返回值的体现(响应请求)
携带状态码
携带错误信息
返回值
get 返回查看的所有或单条信息
post 返回新增的那条数据
put/patch 返回更新的那条数据
delete 返回空
携带超链接
二,序列化组件
1、序列化
实现流程
1.如果设置了many=True
2.把queryset当成可迭代对象去循环,得到每个模型对象
3.把每个模型对象放入序列化器进行序列化
4.进行字段匹配,匹配上的字段进行序列化,匹配不上的丢弃
5.序列化的时候必须满足序列化的所有字段要求
声明一个序列化器
class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) # required=False 忽略校验 title = serializers.CharField(max_length=32) pub_time = serializers.DateField()
在视图中引用我们定义的序列化器,序列化我们的queryset数据
ser_obj = BookSerializer(queryset, many=True) # many=True 支持(当成)可迭代对象,循环遍历并序列化 ser_obj = BookSerializer(models_obj) # 同样支持单个模型对象的序列化
ser_obj.validated_data # 校验通过的数据
return Response(ser_obj.data)
2、反序列化
获取前端传过来的数据
用序列化器进行校验
BookSerializer(data=request.data) if ser_obj.is_valid(): ser_obj.save() # 调用序列化器中的create方法操作orm创建新对象 return Response(ser_obj.data) else: return Response
3、序列化以及反序列化的时候字段类型不统一的情况
-- required=False # 对字段取消校验 -- read_only=True # 仅序列化是进行校验 -- write_only=True # 仅反序列化是校验
4、ModeSerializer 帮我们实现create以及update方法
class BookSerializer(serilalizers.ModelSerializer) # SerializerMethodField方法字段,会将钩子方法的返回值给字段 text = serializers.SerializerMethodField(read_only=True) class Meta: model = Book # 模型类 fields = "__all__" / ["",""] exclude = [""] # 排除某些字段 depth = 1 # 根据你的外键关系找几层,会让你所有的外键变成read_only = True extra_kwargs = { "字段名称":{参数:值} # 为自动生成的字段添加参数 } # SerializerMethodField的钩子方法定义 def get_字段名称(self,obj): obj 是我们循环序列化的每个模型对象 return 自己想要的数据
4.字段的校验方法
多个字段的校验方法,优先级为 低
def validate(self,attrs): # attrs 前端传过来的所有的数据组成的字典 raise serializers.ValidationError("xxxx") return value
单个字段的校验方法,优先级为 中
def validate_字段名(self,value): # value字段的值 raise serializers.ValidationError("xxxx") return value
自定义校验方法,优先级为 高
# 字段中添加validators指定校验方法 title = serializers.CharField(max_length=32,validators=[my_validate]) def my_validate(value): raise serializers.ValidationError("xxxx") return value
三,视图组件
视图的封装
class GenericAPIView(APIView): query_set = None serializer_class = None def get_query_set(self): return self.query_set # 从对象属性开始找 def get_serializer(self, *args, **kwargs): # 序列化器实例化时,以传参的方式执行 return self.serializer_class(*args, **kwargs) class RetrieveModelMixin(object): def retrieve(self, request, pk): book_obj = self.get_query_set().filter(pk=pk).first() ser_obj = self.get_serializer(book_obj) return Response(ser_obj.data) class ListModelMixin(object): def list(self, request): # print(self.action_map) # actions:{‘get‘: ‘list‘, ‘post‘: ‘create‘} ser_obj = self.get_serializer(self.get_query_set(), many=True) return Response(ser_obj.data) class CreateModelMixin(object): def create(self, request): ser_obj = self.get_serializer(data=request.data) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) # print(ser_obj.errors) return Response(ser_obj.errors) class UpdateModelMixin(object): def update(self, request, pk): book_obj = self.get_query_set().filter(pk=pk).first() ser_obj = self.get_serializer(instance=book_obj, data=request.data,partial=True) # 不用每个字段强制都要传值 if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) return Response(ser_obj.errors) class DestoryModelMixin(object): def destory(self, request, pk): book_obj = self.get_query_set().filter(pk=pk).first() if book_obj: book_obj.delete() return Response("") return Response("删除的对象不存在") class ListCreateModeMixin(GenericAPIView, ListModelMixin, CreateModelMixin): pass class RetrieveUpdateDestroyModelMixn(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestoryModelMixin): pass # 继承了ViewSetMixin并使用了它的as_view方法 class ModelViewSet(ViewSetMixin, ListCreateModeMixin, RetrieveUpdateDestroyModelMixn): pass # 第一种CBV class BookListAPIView(ListCreateModeMixin): query_set = Book.objects.all() serializer_class = BookSerializer def get(self, request): return self.list(request) def post(self, request): return self.create(request) class BookEditAPIView(RetrieveUpdateDestroyModelMixn): query_set = Book.objects.all() serializer_class = BookSerializer def get(self, request, id): return self.retrieve(request, id) def put(self, request, id): return self.update(request, id) def delete(self, request, id): return self.destory(request, id) # 第二种,解耦后的CBV class BookModelView(ModelViewSet): query_set = Book.objects.all() # 使用路由系统后,需要queryset serializer_class = BookSerializer # queryset 如果重写视图的话,使用queryset作为参数会被框架放入缓存 # 防止数据不更新,应用调用all()方法重新获取数据 # self.get_queryset() # return self.queryset.all() # 第三种,直接继承框架已定义的ModelViewSet类, from rest_framework.viewsets import ModelViewSet class BookModelView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer class PublisherModelView(ModelViewSet): queryset = Publisher.objects.all() serializer_class = PublisherSerializer class AuthorModelView(ModelViewSet): queryset = Author.objects.all() serializer_class = AuthorSerializer
注意
# 如果不利用ViewSetMixin的as_view方法,对self.get=self.list,如此类推赋值,而是重新的ModelViewSet的话,路由的as_view()方法需要手动穿参,重新指定请求的执行方法 urlpatterns = [ url(r‘^list/$‘, views.BookModelView.as_view({‘get‘:‘list‘,‘post‘:‘create‘})), # 用新的类来处理,由于没有get,post方法, url(r‘^list/(?P<id>\d+)/$‘, views.BookModelView.as_view({‘get‘:‘retrieve‘,‘put‘:‘update‘,‘delete‘:‘destroy‘})), ]
四,路由组件
# 导入 from rest_framwork.routers import DefaultRouter # 实例化 router = DefaultRouter() # 注册 router.register("list",views.BookModelView) # 默认生成的路由都自带参数(pk),所以视图中的方法也要带参数pk # actions={‘get‘: ‘list‘, ‘post‘: ‘create‘} 路由系统自动调用as_view({‘get‘: ‘list‘, ‘post‘: ‘create‘}) # 把默认生成的路由注册 urlpattrens += router.urls # 默认生成的路由都是带参数的!! # ^book/ ^list/$ [name=‘book-list‘] # ^book/ ^list\.(?P<format>[a-z0-9]+)/?$ [name=‘book-list‘] # ^book/ ^list/(?P<pk>[^/.]+)/$ [name=‘book-detail‘] # ^book/ ^list/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name=‘book-detail‘] # ^book/ ^$ [name=‘api-root‘] # ^book/ ^\.(?P<format>[a-z0-9]+)/?$ [name=‘api-root‘]
标签:取数 books 写视图 ram 根据 自带 only ext model
原文地址:https://www.cnblogs.com/lianyeah/p/10129185.html