Coverage for audoma_api/views.py: 94%
99 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-04 07:22 +0000
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-04 07:22 +0000
1from datetime import (
2 date,
3 datetime,
4 time,
5 timedelta,
6)
7from decimal import Decimal
9from audoma_api.exceptions import (
10 CustomBadRequestException,
11 CustomConflictException,
12)
13from audoma_api.models import (
14 Car,
15 ExampleFileModel,
16 ExampleModel,
17 ExamplePerson,
18 Manufacturer,
19)
20from audoma_api.permissions import (
21 AlternatePermission1,
22 AlternatePermission2,
23 DetailPermission,
24 ViewAndDetailPermission,
25 ViewPermission,
26)
27from audoma_api.serializers import (
28 CarModelSerializer,
29 ExampleFileModelSerializer,
30 ExampleModelCreateSerializer,
31 ExampleModelSerializer,
32 ExampleOneFieldSerializer,
33 ExamplePersonModelSerializer,
34 ExampleSerializer,
35 ManufacturerModelSerializer,
36 MutuallyExclusiveExampleSerializer,
37)
38from django_filters import rest_framework as df_filters
39from rest_framework.decorators import action
40from rest_framework.exceptions import NotFound
41from rest_framework.filters import SearchFilter
42from rest_framework.parsers import MultiPartParser
43from rest_framework.permissions import IsAuthenticated
44from rest_framework.response import Response
46from audoma.decorators import audoma_action
47from audoma.drf import (
48 mixins,
49 viewsets,
50)
51from audoma.drf.filters import DocumentedTypedChoiceFilter
54class ExampleViewSet(
55 mixins.ActionModelMixin,
56 mixins.CreateModelMixin,
57 mixins.RetrieveModelMixin,
58 mixins.DestroyModelMixin,
59 mixins.ListModelMixin,
60 viewsets.GenericViewSet,
61):
62 permission_classes = [
63 IsAuthenticated,
64 ViewAndDetailPermission,
65 DetailPermission,
66 ViewPermission,
67 AlternatePermission1 | AlternatePermission2,
68 ]
70 serializer_class = ExampleSerializer
71 queryset = {}
73 @action(detail=True, methods=["post"])
74 def detail_action(self, request, pk=None):
75 return Response({}) # wrong
77 @action(detail=False, methods=["post"])
78 def non_detail_action(self, request):
79 return Response({}) # wrong
82example_choice = DocumentedTypedChoiceFilter(
83 ExampleModel.EXAMPLE_CHOICES, "choice", lookup_expr="exact", field_name="choices"
84)
87class ExampleChoiceFilter(df_filters.FilterSet):
88 choice = example_choice
90 class Meta:
91 model = ExampleModel
92 fields = [
93 "choice",
94 ]
97class ExampleModelViewSet(
98 mixins.ActionModelMixin,
99 mixins.CreateModelMixin,
100 mixins.RetrieveModelMixin,
101 mixins.DestroyModelMixin,
102 mixins.ListModelMixin,
103 viewsets.GenericViewSet,
104):
106 permission_classes = [
107 IsAuthenticated,
108 ViewAndDetailPermission,
109 DetailPermission,
110 ViewPermission,
111 AlternatePermission1 | AlternatePermission2,
112 ]
114 filterset_class = ExampleChoiceFilter
115 serializer_class = ExampleModelSerializer
116 queryset = ExampleModel.objects.all()
118 @audoma_action(
119 detail=True,
120 methods=["get"],
121 results={"get": "GET method is not allowed"},
122 collectors=None,
123 )
124 def detail_action(self, request, pk=None):
125 return Response({}) # wrong
127 @action(detail=False, methods=["post"])
128 def non_detail_action(self, request):
129 return Response({}) # wron
132class ExamplePersonModelViewSet(
133 mixins.ActionModelMixin,
134 mixins.CreateModelMixin,
135 mixins.RetrieveModelMixin,
136 mixins.DestroyModelMixin,
137 mixins.ListModelMixin,
138 viewsets.GenericViewSet,
139):
140 permission_classes = [
141 IsAuthenticated,
142 ViewAndDetailPermission,
143 DetailPermission,
144 ViewPermission,
145 ]
147 serializer_class = ExamplePersonModelSerializer
148 queryset = ExamplePerson.objects.all()
150 @action(detail=True, methods=["post"])
151 def detail_action(self, request, pk=None):
152 return Response({})
154 @action(detail=False, methods=["post"])
155 def non_detail_action(self, request):
156 return Response({})
159class ExampleFileUploadViewSet(
160 mixins.ActionModelMixin,
161 mixins.CreateModelMixin,
162 viewsets.GenericViewSet,
163):
164 serializer_class = ExampleFileModelSerializer
165 queryset = ExampleFileModel.objects.all()
167 parser_classes = [MultiPartParser]
170class ManufacturerViewSet(
171 mixins.ActionModelMixin,
172 mixins.BulkCreateModelMixin,
173 mixins.UpdateModelMixin,
174 mixins.ListModelMixin,
175 mixins.DestroyModelMixin,
176 mixins.BulkUpdateModelMixin,
177 mixins.RetrieveModelMixin,
178 viewsets.GenericViewSet,
179):
180 queryset = Manufacturer.objects.all()
181 serializer_class = ManufacturerModelSerializer
184class CarViewSet(
185 mixins.ActionModelMixin,
186 mixins.RetrieveModelMixin,
187 mixins.ListModelMixin,
188 viewsets.GenericViewSet,
189):
190 queryset = Car.objects.none()
191 serializer_class = CarModelSerializer
193 filter_backends = [SearchFilter, df_filters.DjangoFilterBackend]
195 filterset_fields = ["engine_type"]
196 search_fields = ["=manufacturer", "name"]
199class MutuallyExclusiveViewSet(
200 mixins.ActionModelMixin,
201 mixins.CreateModelMixin,
202 mixins.ListModelMixin,
203 viewsets.GenericViewSet,
204):
205 serializer_class = MutuallyExclusiveExampleSerializer
208class ExampleModelPermissionLessViewSet(
209 mixins.ActionModelMixin, viewsets.GenericViewSet
210):
211 serializer_class = ExampleModelSerializer
212 queryset = ExampleModel.objects.all()
214 @audoma_action(
215 detail=True,
216 methods=["post"],
217 collectors={"post": ExampleModelCreateSerializer},
218 results={"post": {201: ExampleModelSerializer, 202: ExampleOneFieldSerializer}},
219 )
220 def detail_action(self, request, collect_serializer, pk=None):
221 if request.data.pop("usertype", None):
222 return collect_serializer.save(), 201
223 return {"rate": ExampleOneFieldSerializer.RATES.LIKE}, 202
225 @audoma_action(
226 detail=False,
227 methods=["get"],
228 results={"get": {200: "This is a test view", 404: "Not found"}},
229 )
230 def non_detail_action(self, request):
231 return None, 200
233 @audoma_action(
234 detail=False,
235 methods=["post"],
236 results=ExampleOneFieldSerializer,
237 collectors=ExampleOneFieldSerializer,
238 )
239 def rate_create_action(self, request, collect_serializer):
240 return collect_serializer.save(), 201
242 @audoma_action(detail=True, methods=["get"], results=ExampleOneFieldSerializer)
243 def specific_rate(self, request, pk=None):
244 return {"rate": ExampleOneFieldSerializer.RATES.DISLIKIE}, 200
246 @audoma_action(
247 detail=False,
248 methods=["get"],
249 results=ExampleOneFieldSerializer,
250 errors=[CustomBadRequestException(), CustomConflictException],
251 )
252 def properly_defined_exception_example(self, request):
253 raise CustomConflictException("Some custom message, that should be accepted")
255 @audoma_action(detail=False, methods=["get"])
256 def proper_usage_of_common_errors(self, request):
257 raise NotFound
259 @audoma_action(
260 detail=False,
261 methods=["get"],
262 results=ExampleOneFieldSerializer,
263 )
264 def improperly_defined_exception_example(self, request):
265 raise CustomBadRequestException
267 def get_object(self):
268 return ExampleModel(
269 char_field="TESTChar",
270 phone_number="+18888888822",
271 email="test@iteo.com",
272 url="http://localhost:8000/redoc/",
273 boolean=False,
274 nullboolean=None,
275 mac_adress="96:82:2E:6B:F5:49",
276 slug="tst",
277 uuid="14aefe15-7c96-49b6-9637-7019c58c25d2",
278 ip_address="192.168.10.1",
279 integer=16,
280 _float=12.2,
281 decimal=Decimal("13.23"),
282 datetime=datetime(2009, 11, 13, 10, 39, 35),
283 date=date(2009, 11, 13),
284 time=time(10, 39, 35),
285 duration=timedelta(days=1),
286 choices=1,
287 json="",
288 )
290 @audoma_action(
291 detail=True,
292 methods=["put", "patch"],
293 collectors=ExampleModelCreateSerializer,
294 results=ExampleModelSerializer,
295 )
296 def example_update_action(self, request, collect_serializer, pk=None):
297 return collect_serializer.save(), 201