9个视图子类
1'''
29个视图子类
3from rest_framework.generics import ListAPIView, CreateAPIView, ListCreateAPIView, UpdateAPIView, DestroyAPIView,RetrieveAPIView,RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView, RetrieveUpdateAPIView
4'''
5
6class CreateAPIView(mixins.CreateModelMixin, # mixins是一个py文件
7 GenericAPIView):
8 """
9 Concrete view for creating a model instance.
10 """
11 def post(self, request, *args, **kwargs):
12 return self.create(request, *args, **kwargs)
13
14
15class ListAPIView(mixins.ListModelMixin,
16 GenericAPIView):
17 """
18 Concrete view for listing a queryset.
19 """
20 def get(self, request, *args, **kwargs):
21 return self.list(request, *args, **kwargs)
22
23
24class RetrieveAPIView(mixins.RetrieveModelMixin,
25 GenericAPIView):
26 """
27 Concrete view for retrieving a model instance.
28 """
29 def get(self, request, *args, **kwargs):
30 return self.retrieve(request, *args, **kwargs)
31
32
33class DestroyAPIView(mixins.DestroyModelMixin,
34 GenericAPIView):
35 """
36 Concrete view for deleting a model instance.
37 """
38 def delete(self, request, *args, **kwargs):
39 return self.destroy(request, *args, **kwargs)
40
41
42class UpdateAPIView(mixins.UpdateModelMixin,
43 GenericAPIView):
44 """
45 Concrete view for updating a model instance.
46 """
47 def put(self, request, *args, **kwargs):
48 return self.update(request, *args, **kwargs)
49
50 def patch(self, request, *args, **kwargs):
51 return self.partial_update(request, *args, **kwargs)
52
53
54class ListCreateAPIView(mixins.ListModelMixin,
55 mixins.CreateModelMixin,
56 GenericAPIView):
57 """
58 Concrete view for listing a queryset or creating a model instance.
59 """
60 def get(self, request, *args, **kwargs):
61 return self.list(request, *args, **kwargs)
62
63 def post(self, request, *args, **kwargs):
64 return self.create(request, *args, **kwargs)
65
66
67class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
68 mixins.UpdateModelMixin,
69 GenericAPIView):
70 """
71 Concrete view for retrieving, updating a model instance.
72 """
73 def get(self, request, *args, **kwargs):
74 return self.retrieve(request, *args, **kwargs)
75
76 def put(self, request, *args, **kwargs):
77 return self.update(request, *args, **kwargs)
78
79 def patch(self, request, *args, **kwargs):
80 return self.partial_update(request, *args, **kwargs)
81
82
83class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
84 mixins.DestroyModelMixin,
85 GenericAPIView):
86 """
87 Concrete view for retrieving or deleting a model instance.
88 """
89 def get(self, request, *args, **kwargs):
90 return self.retrieve(request, *args, **kwargs)
91
92 def delete(self, request, *args, **kwargs):
93 return self.destroy(request, *args, **kwargs)
94
95
96class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
97 mixins.UpdateModelMixin,
98 mixins.DestroyModelMixin,
99 GenericAPIView):
100 """
101 Concrete view for retrieving, updating or deleting a model instance.
102 """
103 def get(self, request, *args, **kwargs):
104 return self.retrieve(request, *args, **kwargs)
105
106 def put(self, request, *args, **kwargs):
107 return self.update(request, *args, **kwargs)
108
109 def patch(self, request, *args, **kwargs):
110 return self.partial_update(request, *args, **kwargs)
111
112 def delete(self, request, *args, **kwargs):
113 return self.destroy(request, *args, **kwargs)
5个视图扩展类
1from rest_framework import status
2from rest_framework.response import Response
3from rest_framework.settings import api_settings
4
5
6class CreateModelMixin:
7 """
8 Create a model instance.
9 """
10 def create(self, request, *args, **kwargs):
11 serializer = self.get_serializer(data=request.data)
12 serializer.is_valid(raise_exception=True)
13 self.perform_create(serializer)
14 headers = self.get_success_headers(serializer.data)
15 return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
16
17
18 def perform_create(self, serializer):
19 serializer.save()
20
21 def get_success_headers(self, data):
22 try:
23 return {'Location': str(data[api_settings.URL_FIELD_NAME])}
24 except (TypeError, KeyError):
25 return {}
26
27
28class ListModelMixin:
29 """
30 List a queryset.
31 """
32 def list(self, request, *args, **kwargs):
33 queryset = self.filter_queryset(self.get_queryset())
34
35 page = self.paginate_queryset(queryset)
36 if page is not None:
37 serializer = self.get_serializer(page, many=True)
38 return self.get_paginated_response(serializer.data)
39
40 serializer = self.get_serializer(queryset, many=True)
41 return Response(serializer.data)
42
43
44class RetrieveModelMixin:
45 """
46 Retrieve a model instance.
47 """
48 def retrieve(self, request, *args, **kwargs):
49 instance = self.get_object()
50 serializer = self.get_serializer(instance)
51 return Response(serializer.data)
52
53
54class UpdateModelMixin:
55 """
56 Update a model instance.
57 """
58 def update(self, request, *args, **kwargs):
59 partial = kwargs.pop('partial', False)
60 instance = self.get_object()
61 serializer = self.get_serializer(instance, data=request.data, partial=partial)
62 serializer.is_valid(raise_exception=True)
63 self.perform_update(serializer)
64
65 if getattr(instance, '_prefetched_objects_cache', None):
66
67
68 instance._prefetched_objects_cache = {}
69
70 return Response(serializer.data)
71
72 def perform_update(self, serializer):
73 serializer.save()
74
75 def partial_update(self, request, *args, **kwargs):
76 kwargs['partial'] = True
77 return self.update(request, *args, **kwargs)
78
79
80class DestroyModelMixin:
81 """
82 Destroy a model instance.
83 """
84 def destroy(self, request, *args, **kwargs):
85 instance = self.get_object()
86 self.perform_destroy(instance)
87 return Response(status=status.HTTP_204_NO_CONTENT)
88
89 def perform_destroy(self, instance):
90 instance.delete()
GenericAPIView
1from django.core.exceptions import ValidationError
2from django.db.models.query import QuerySet
3from django.http import Http404
4from django.shortcuts import get_object_or_404 as _get_object_or_404
5
6from rest_framework import mixins, views
7from rest_framework.settings import api_settings
8
9
10class GenericAPIView(views.APIView):
11 """
12 Base class for all other generic views.
13 """
14
15
16
17
18
19
20 queryset = None
21 serializer_class = None
22
23
24
25 lookup_field = 'pk'
26 lookup_url_kwarg = None
27
28
29 filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
30
31
32 pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
33
34 def get_queryset(self):
35 """
36 Get the list of items for this view.
37 This must be an iterable, and may be a queryset.
38 Defaults to using `self.queryset`.
39
40 This method should always be used rather than accessing `self.queryset`
41 directly, as `self.queryset` gets evaluated only once, and those results
42 are cached for all subsequent requests.
43
44 You may want to override this if you need to provide different
45 querysets depending on the incoming request.
46
47 (Eg. return a list of items that is specific to the user)
48 """
49 assert self.queryset is not None, (
50 "'%s' should either include a `queryset` attribute, "
51 "or override the `get_queryset()` method."
52 % self.__class__.__name__
53 )
54
55 queryset = self.queryset
56 if isinstance(queryset, QuerySet):
57
58 queryset = queryset.all()
59 return queryset
60
61 def get_object(self):
62 """
63 Returns the object the view is displaying.
64
65 You may want to override this if you need to provide non-standard
66 queryset lookups. Eg if objects are referenced using multiple
67 keyword arguments in the url conf.
68 """
69 queryset = self.filter_queryset(self.get_queryset())
70
71
72 lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
73
74 assert lookup_url_kwarg in self.kwargs, (
75 'Expected view %s to be called with a URL keyword argument '
76 'named "%s". Fix your URL conf, or set the `.lookup_field` '
77 'attribute on the view correctly.' %
78 (self.__class__.__name__, lookup_url_kwarg)
79 )
80
81 filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
82 obj = get_object_or_404(queryset, **filter_kwargs)
83
84
85 self.check_object_permissions(self.request, obj)
86
87 return obj
88
89 def get_serializer(self, *args, **kwargs):
90 """
91 Return the serializer instance that should be used for validating and
92 deserializing input, and for serializing output.
93 """
94 serializer_class = self.get_serializer_class()
95 kwargs.setdefault('context', self.get_serializer_context())
96 return serializer_class(*args, **kwargs)
97
98 def get_serializer_class(self):
99 """
100 Return the class to use for the serializer.
101 Defaults to using `self.serializer_class`.
102
103 You may want to override this if you need to provide different
104 serializations depending on the incoming request.
105
106 (Eg. admins get full serialization, others get basic serialization)
107 """
108 assert self.serializer_class is not None, (
109 "'%s' should either include a `serializer_class` attribute, "
110 "or override the `get_serializer_class()` method."
111 % self.__class__.__name__
112 )
113
114 return self.serializer_class
115
116 def get_serializer_context(self):
117 """
118 Extra context provided to the serializer class.
119 """
120 return {
121 'request': self.request,
122 'format': self.format_kwarg,
123 'view': self
124 }
125
126 def filter_queryset(self, queryset):
127 """
128 Given a queryset, filter it with whichever filter backend is in use.
129
130 You are unlikely to want to override this method, although you may need
131 to call it either from a list view, or from a custom `get_object`
132 method if you want to apply the configured filtering backend to the
133 default queryset.
134 """
135 for backend in list(self.filter_backends):
136 queryset = backend().filter_queryset(self.request, queryset, self)
137 return queryset
封装
1
2
3
4有两个参数:query=models.Book.object.all()
5 serializers_class=BookSerializers
6三个方法:
7get_serializers()
8get_query()
9get_object()
10
11
12from generics import GenericAPIView
13
14class PublishSerializer(GenericAPIView):
15 queryset = models.Publish.objects.all()
16 serializer_class = MySerializer
17 def get(self, request):
18 publish_list = self.get_queryset()
19 res = self.get_serializer(instance=publish_list, many=True)
20 return Response(data=res.data)
21
22
23from rest_framework.mixins import UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin,ListModelMixin,CreateModelMixin
24
25class PublishSerializer(GenericAPIView, ListModelMixin):
26 queryset = models.Publish.objects.all()
27 serializer_class = MySerializer
28 def get(self, request):
29 return self.list(request)
30
31
32两个get请求时分开的,需要写两个类
33
34from rest_framework.generics import ListAPIView, CreateAPIView, ListCreateAPIView, UpdateAPIView, DestroyAPIView,RetrieveAPIView,RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView, RetrieveUpdateAPIView
35
36
37class PublishSerializer(CreateAPIView):
38 queryset = models.Publish.objects.all()
39 serializer_class = MySerializer
40
41
42from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet, ViewSet, ViewSetMixin, GenericViewSet
43'''
44ModelViewSet继承了GenericAPIView和所有的Mixin方法(UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin,ListModelMixin,CreateModelMixin),所以,只要继承了ModelViewSet,就相当于写了5个接口
45ViewSetMixin:魔法方法,只要继承了它,路由as_view({字典}),必须写在最左侧
46ViewSet继承了ViewSetMixin和APIView
47GenericViewSet继承了ViewSetMixin和GenericAPIView
48'''
49
50 class PublishView(ModelViewSet):
51 queryset = Publish.objects.all()
52 serializer_class = PublishSerializer
53
54 class PublishView(ReadOnlyModelViewSet):
55 queryset = Publish.objects.all()
56 serializer_class = PublishSerializer
57
58'''
59一个类里写5个接口,有2个get请求,如何书写路由
60'''
路由组件
1
2ViewSetMixin重写了as_view方法,并且ViewSetMixin必须写在继承关系的最左侧,会按照从左到右的方式查找as_view方法
3
4
5
6
7path('publish/', views.PublishView.as_view(actions={'get': 'list','post':'create'}))
8
9
10
11 在urls.py中
12 1、第一步导入路由的类
13 from rest_framework.routers import SimpleRouter,DefaultRouter
14 '''
15 SimpleRouter,DefaultRouter区别,DefaultRouter会多创建一个根路由,显示所有的路由信息,但是有时会出现问题, 建议使用SimpleRouter
16 '''
17 2、第二步:类实例化得到对象(不用传参数)
18 router=SimpleRouter()
19 3、第三步:注册视图类,
20 router.register('publish',views.PublishView,'publish')
21
22
23
24
25 4、第四步:加入到总路由中(两种方式)
26
27 urlpatterns = [
28
29 path('api/v1/', include(router.urls)),
30 ]
31
32 urlpatterns+=router.urls
33
34
35
36
37
38from rest_framework.decorate import action
39class Login(ViewSet):
40 @action(methods=['GET','POST'],detail=False)
41 def login(self,request):
42 return Response('ok')
43
44
45
46 -第一种:path('publish/', views.PublishView.as_view(actions={'get': 'list','post':'create'}))
47 -第二种:自动生成 (SimpleRouter,DefaultRouter)
48 -action有什么用
49 -5个方法:create,list,destory。。,不需要使用action映射
50 -如果继承的是 ViewSetMixin, views.APIView +5个视图扩展类之一或者9个视图子类,这种不需要使用action装饰器