1 from rest_framework import generics
2 from rest_framework import serializers
3 from rest_framework.response import Response
4 from rest_framework import status
6 """ PlusSerializerMixin
8 Implements Serializer fields that are common to all OpenCloud objects. For
9 example, stuff related to backend fields.
12 class PlusSerializerMixin():
13 backendIcon = serializers.SerializerMethodField("getBackendIcon")
14 backendHtml = serializers.SerializerMethodField("getBackendHtml")
16 # This will cause a descendant class to pull in the methods defined
17 # above. See rest_framework/serializers.py: _get_declared_fields().
18 base_fields = {"backendIcon": backendIcon, "backendHtml": backendHtml}
19 # Rest_framework 3.0 uses _declared_fields instead of base_fields
20 _declared_fields = {"backendIcon": backendIcon, "backendHtml": backendHtml}
22 def getBackendIcon(self, obj):
23 return obj.getBackendIcon()
25 def getBackendHtml(self, obj):
26 return obj.getBackendHtml()
28 # XXX this was lifted and hacked up a bit from genapi.py
29 class PlusListCreateAPIView(generics.ListCreateAPIView):
30 def create(self, request, *args, **kwargs):
31 serializer = self.get_serializer(data=request.DATA, files=request.FILES)
32 if not (serializer.is_valid()):
33 response = {"error": "validation",
34 "specific_error": "not serializer.is_valid()",
\r
35 "reasons": serializer.errors}
\r
36 return Response(response, status=status.HTTP_400_BAD_REQUEST)
37 obj = serializer.object
38 obj.caller = request.user
39 if obj.can_update(request.user):
40 return super(PlusListCreateAPIView, self).create(request, *args, **kwargs)
42 raise Exception("failed obj.can_update")
44 ret = super(PlusListCreateAPIView, self).create(request, *args, **kwargs)
45 if (ret.status_code%100 != 200):
46 raise Exception(ret.data)
50 # XXX this is taken from genapi.py
51 # XXX find a better way to re-use the code
52 class PlusRetrieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
54 # To handle fine-grained field permissions, we have to check can_update
55 # the object has been updated but before it has been saved.
57 def update(self, request, *args, **kwargs):
\r
58 partial = kwargs.pop('partial', False)
\r
59 self.object = self.get_object_or_none()
\r
61 serializer = self.get_serializer(self.object, data=request.DATA,
\r
62 files=request.FILES, partial=partial)
\r
64 if not serializer.is_valid():
\r
65 response = {"error": "validation",
\r
66 "specific_error": "not serializer.is_valid()",
\r
67 "reasons": serializer.errors}
\r
68 return Response(response, status=status.HTTP_400_BAD_REQUEST)
\r
71 self.pre_save(serializer.object)
\r
72 except ValidationError as err:
\r
73 # full_clean on model instance may be called in pre_save,
\r
74 # so we have to handle eventual errors.
\r
75 response = {"error": "validation",
\r
76 "specific_error": "ValidationError in pre_save",
\r
77 "reasons": err.message_dict}
\r
78 return Response(response, status=status.HTTP_400_BAD_REQUEST)
\r
80 if serializer.object is not None:
\r
81 if not serializer.object.can_update(request.user):
\r
82 return Response(status=status.HTTP_400_BAD_REQUEST)
\r
84 if self.object is None:
\r
85 self.object = serializer.save(force_insert=True)
\r
86 self.post_save(self.object, created=True)
\r
87 return Response(serializer.data, status=status.HTTP_201_CREATED)
\r
89 self.object = serializer.save(force_update=True)
\r
90 self.post_save(self.object, created=False)
\r
91 return Response(serializer.data, status=status.HTTP_200_OK)
93 def destroy(self, request, *args, **kwargs):
94 obj = self.get_object()
95 if obj.can_update(request.user):
96 return super(generics.RetrieveUpdateDestroyAPIView, self).destroy(request, *args, **kwargs)
98 return Response(status=status.HTTP_400_BAD_REQUEST)