Coverage for audoma/drf/generics.py: 73%
30 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-08 06:12 +0000
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-08 06:12 +0000
1from typing import Type
3from rest_framework import generics
4from rest_framework.serializers import BaseSerializer
7class GenericAPIView(generics.GenericAPIView):
9 """
10 Extended GenericAPIView known from rest_framework.
11 This class extends `get_serializer` and `get_serializer_class` methods.
12 Also provides `get_result_serializer`, which is a shourtcut for `get_serializer` with proper param.
13 """
15 def get_serializer(self, *args, **kwargs) -> BaseSerializer:
16 """
17 Passes additional param to `get_serializer_class`.
19 kwargs:
20 serializer_type - defines if serializer is collect or result serializer.
21 result serializer will be used to produce response, collect to process incoming data.
22 serializer_class - it is possible to pass serializer_class to get_serializer, this will
23 ends with returning passed serializer_class object.
25 Returns:
26 Object of obtained serializer class.
27 """
28 many = kwargs.get("many", False)
30 serializer_type = kwargs.pop("serializer_type", "collect")
31 serializer_class = kwargs.pop(
32 "serializer_class",
33 self.get_serializer_class(type=serializer_type, many=many),
34 )
35 kwargs["context"] = self.get_serializer_context()
37 return serializer_class(*args, **kwargs)
39 # needed by AudomaSwaggerAutoSchema
40 def get_result_serializer(self, *args, **kwargs) -> BaseSerializer:
41 """
42 Shortuct for get_serializer.
43 Simply has serializer_type set to `result`
44 """
45 return self.get_serializer(*args, serializer_type="result", **kwargs)
47 def get_serializer_class(
48 self, type: str = "collect", many: bool = False
49 ) -> Type[BaseSerializer]:
50 """
51 Extends defuault `get_serializer_class` method.
52 This returns proper serializer_class for current request.
54 Args:
55 type - type of serializer to be returned, it may be collect or result serializer.
57 Returns:
58 This returns serializer_class
60 """
61 assert self.action not in [
62 "post",
63 "put",
64 "delete",
65 "patch",
66 "options",
67 "get",
68 "head",
69 ]
70 method = self.request.method.lower()
71 if self.action == "metadata":
72 action = self.action_map.get("post", "list")
73 else:
74 action = self.action
75 attr_names = [
76 "%s_%s_%s_serializer_class" % (method, action, type),
77 "%s_%s_serializer_class" % (action, type),
78 "%s_%s_serializer_class" % (method, action),
79 "%s_serializer_class" % (action),
80 "common_%s_serializer_class" % (type),
81 "serializer_class",
82 ]
83 for attr_name in attr_names:
84 try:
85 serializer_class = getattr(self, attr_name)
86 except AttributeError:
87 continue
88 else:
89 break
91 assert serializer_class is not None, (
92 "'%s' should either include a `serializer_class` attribute, "
93 "or override the `get_serializer_class()` method." % self.__class__.__name__
94 )
96 if (
97 type == "result"
98 and self.action != "list"
99 and hasattr(serializer_class, "get_result_serializer_class")
100 ):
101 assert callable(serializer_class.get_result_serializer_class)
102 serializer_class = serializer_class.get_result_serializer_class(many=many)
104 return serializer_class