sliceplus support for site_allocation and network_ports for tenant view
[plstackapi.git] / planetstack / core / xoslib / methods / plus.py
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
5
6 """ PlusSerializerMixin
7
8     Implements Serializer fields that are common to all OpenCloud objects. For
9     example, stuff related to backend fields.
10 """
11 \r
12 class PlusSerializerMixin():
13     backendIcon = serializers.SerializerMethodField("getBackendIcon")
14     backendHtml = serializers.SerializerMethodField("getBackendHtml")
15
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}
21
22     def getBackendIcon(self, obj):
23         return obj.getBackendIcon()
24
25     def getBackendHtml(self, obj):
26         return obj.getBackendHtml()
27
28 # XXX this is taken from genapi.py
29 # XXX find a better way to re-use the code
30 class PlusRetrieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
31
32     # To handle fine-grained field permissions, we have to check can_update
33     # the object has been updated but before it has been saved.
34
35     def update(self, request, *args, **kwargs):\r
36         partial = kwargs.pop('partial', False)\r
37         self.object = self.get_object_or_none()\r
38 \r
39         serializer = self.get_serializer(self.object, data=request.DATA,\r
40                                          files=request.FILES, partial=partial)\r
41 \r
42         if not serializer.is_valid():\r
43             response = {"error": "validation",\r
44                         "specific_error": "not serializer.is_valid()",\r
45                         "reasons": serializer.errors}\r
46             return Response(response, status=status.HTTP_400_BAD_REQUEST)\r
47 \r
48         try:\r
49             self.pre_save(serializer.object)\r
50         except ValidationError as err:\r
51             # full_clean on model instance may be called in pre_save,\r
52             # so we have to handle eventual errors.\r
53             response = {"error": "validation",\r
54                          "specific_error": "ValidationError in pre_save",\r
55                          "reasons": err.message_dict}\r
56             return Response(response, status=status.HTTP_400_BAD_REQUEST)\r
57 \r
58         if serializer.object is not None:\r
59             if not serializer.object.can_update(request.user):\r
60                 return Response(status=status.HTTP_400_BAD_REQUEST)\r
61 \r
62         if self.object is None:\r
63             self.object = serializer.save(force_insert=True)\r
64             self.post_save(self.object, created=True)\r
65             return Response(serializer.data, status=status.HTTP_201_CREATED)\r
66 \r
67         self.object = serializer.save(force_update=True)\r
68         self.post_save(self.object, created=False)\r
69         return Response(serializer.data, status=status.HTTP_200_OK)
70
71     def destroy(self, request, *args, **kwargs):
72         obj = self.get_object()
73         if obj.can_update(request.user):
74             return super(generics.RetrieveUpdateDestroyAPIView, self).destroy(request, *args, **kwargs)
75         else:
76             return Response(status=status.HTTP_400_BAD_REQUEST)
77