Django REST framework的各种技巧——4.Generic View
2016-02-01 19:20
756 查看
generic view是django神奇的地方,而restframework遵循了这个powerful的机制
Django REST framework的各种技巧【目录索引】
一个之前的blog,解释django generic view
Django generics view 以及看源码为什么这么重要
url
view
cd 你的virtualevn/local/lib/python2.7/site-packages/rest_framework
请看下面两个文件
generics.py
mixins.py
根据继承关系可以先看下ListCreateAPIView,可以看到他提供了get post两个方法,你当然可以直接重写这两个方法,然而就不能用他很多内置的东东,所以重写这里并不好,而应该看他对应的mixin
我们已get为例,get中return self.list(request, *args, **kwargs),而这个东东是mixins.ListModelMixin里面的方法
所以在这里你就知道为嘛restframework在class上要定义一个queryset或者实现get_queryset方法(请继续看generic view的代码部分,我不贴了),为嘛class上定义一个filter_backends可以实现继续的filter
其他的各种mixin各位同学自己看代码就知道了,举一反三我不再赘述。
Django REST framework的各种技巧【目录索引】
写在上面
所有的代码都是在下面的两个版本来做的django==1.8.8 djangorestframework==3.2.5
一个之前的blog,解释django generic view
Django generics view 以及看源码为什么这么重要
一组标准的api的实现实现
例如有一个课程类的api,支持增删改查url
url(r'^courses/$', CoursesView.as_view(), name='course-list'), url(r'^course/(?P<pk>\d+)/$', CourseDetailView.as_view(), name='course-detail'),
view
class CoursesView(ListCreateAPIView): filter_backends = (SchoolPermissionFilterBackend, filters.DjangoFilterBackend, filters.SearchFilter) permission_classes = (IsAuthenticated, ModulePermission) queryset = Course.objects.filter(is_active=True).order_by('-id') filter_fields = ('term',) search_fields = ('name', 'teacher', 'school__name') module_perms = ['course.course'] def get_serializer_class(self): if self.request.method in SAFE_METHODS: return CourseFullMessageSerializer else: return CourseSerializer def get_queryset(self): return Course.objects.select_related('school', ).filter( is_active=True, school__is_active=True, term__is_active=True).order_by('-id') @POST('school', validators='required') def create(self, request, school, *args, **kwargs): if not SchoolPermissionFilterBackend().has_school_permission(request.user, school): raise Error(errors.PermissionDenied, err_message=u'没有对应学校的权限', message=u'没有对应学校的权限') serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(CourseFullMessageSerializer(serializer.instance).data, status=status.HTTP_201_CREATED, headers=headers class CourseDetailView(UnActiveModelMixin, DeleteForeignObjectRelModelMixin, RetrieveUpdateDestroyAPIView): filter_backends = [SchoolPermissionFilterBackend,] serializer_class = CourseSerializer permission_classes = (IsAuthenticated, ModulePermission) queryset = Course.objects.filter(is_active=True).order_by('-id') module_perms = ['course.course'] def get_serializer_class(self): if self.request.method in SAFE_METHODS: return CourseFullMessageSerializer else: return CourseSerializer def retrieve(self, request, *args, **kwargs): instance = self.get_object() school = instance.school if not SchoolPermissionFilterBackend().has_school_permission(request.user, school): raise Error(errors.PermissionDenied, err_message=u'没有对应学校的权限', message=u'没有对应学校的权限') serializer = self.get_serializer(instance) return Response(serializer.data) @POST('school', validators='required') def update(self, request, school, *args, **kwargs): if not SchoolPermissionFilterBackend().has_school_permission(request.user, school): raise Error(errors.PermissionDenied, err_message=u'没有对应学校的权限', message=u'没有对应学校的权限') partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) return Response(CourseFullMessageSerializer(serializer.instance).data) def destroy(self, request, *args, **kwargs): instance = self.get_object() school = instance.school if not SchoolPermissionFilterBackend().has_school_permission(request.user, school): raise Error(errors.PermissionDenied, err_message=u'没有对应学校的权限', message=u'没有对应学校的权限') return super(CourseDetailView, self).destroy(request, *args, **kwargs)
怎么知道重写什么方法?
可以看到我根据需求重写了一些方法,那么到底应该重写那些方法呢?cd 你的virtualevn/local/lib/python2.7/site-packages/rest_framework
请看下面两个文件
generics.py
mixins.py
根据继承关系可以先看下ListCreateAPIView,可以看到他提供了get post两个方法,你当然可以直接重写这两个方法,然而就不能用他很多内置的东东,所以重写这里并不好,而应该看他对应的mixin
class ListCreateAPIView(mixins.ListModelMixin, mixins.CreateModelMixin, GenericAPIView): """ Concrete view for listing a queryset or creating a model instance. """ def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs)
我们已get为例,get中return self.list(request, *args, **kwargs),而这个东东是mixins.ListModelMixin里面的方法
class ListModelMixin(object): """ List a queryset. """ def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)
所以在这里你就知道为嘛restframework在class上要定义一个queryset或者实现get_queryset方法(请继续看generic view的代码部分,我不贴了),为嘛class上定义一个filter_backends可以实现继续的filter
其他的各种mixin各位同学自己看代码就知道了,举一反三我不再赘述。
相关文章推荐
- django中使用jquery ajax post数据出现403错误的解决办法(两种方法)
- django使用ajax post数据出现403错误如何解决
- windows+apache+mod_python配置django运行环境
- python Django连接MySQL数据库做增删改查
- django自定义Field实现一个字段存储以逗号分隔的字符串
- 在Python的Django框架中加载模版的方法
- 在Django中使用Sitemap的方法讲解
- 详解Django中的form库的使用
- Django中的CACHE_BACKEND参数和站点级Cache设置
- 剖析Django中模版标签的解析与参数传递
- Python中DJANGO简单测试实例
- Python的Django框架中的数据库配置指南
- 在Django的上下文中设置变量的方法
- 在Python的Django框架中编写编译函数
- 在Django的URLconf中进行函数导入的方法
- Restful传递数组参数及注解大全
- SpringMVC restful 注解之@RequestBody进行json与object转换
- 在Python的Django框架中生成CSV文件的方法
- 在主机商的共享服务器上部署Django站点的方法
- 使用Python的Django框架中的压缩组件Django Compressor