| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
 | """
Generic views that provide commmonly needed behaviour.
"""
from rest_framework import views, mixins
from rest_framework.settings import api_settings
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.list import MultipleObjectMixin
### Base classes for the generic views ###
class BaseView(views.APIView):
    """
    Base class for all other generic views.
    """
    serializer_class = None
    model_serializer_class = api_settings.MODEL_SERIALIZER
    def get_serializer_context(self):
        """
        Extra context provided to the serializer class.
        """
        return {
            'request': self.request,
            'format': self.format_kwarg,
            'view': self
        }
    def get_serializer_class(self):
        """
        Return the class to use for the serializer.
        Use `self.serializer_class`, falling back to constructing a
        model serializer class from `self.model_serializer_class`
        """
        serializer_class = self.serializer_class
        if serializer_class is None:
            class DefaultSerializer(self.model_serializer_class):
                class Meta:
                    model = self.model
            serializer_class = DefaultSerializer
        return serializer_class
    def get_serializer(self, data=None, files=None, instance=None):
        # TODO: add support for files
        # TODO: add support for seperate serializer/deserializer
        serializer_class = self.get_serializer_class()
        context = self.get_serializer_context()
        return serializer_class(data, instance=instance, context=context)
class MultipleObjectBaseView(MultipleObjectMixin, BaseView):
    """
    Base class for generic views onto a queryset.
    """
    pagination_serializer_class = api_settings.PAGINATION_SERIALIZER
    paginate_by = api_settings.PAGINATE_BY
    def get_pagination_serializer_class(self):
        """
        Return the class to use for the pagination serializer.
        """
        class SerializerClass(self.pagination_serializer_class):
            class Meta:
                object_serializer_class = self.get_serializer_class()
        return SerializerClass
    def get_pagination_serializer(self, page=None):
        pagination_serializer_class = self.get_pagination_serializer_class()
        context = self.get_serializer_context()
        return pagination_serializer_class(instance=page, context=context)
class SingleObjectBaseView(SingleObjectMixin, BaseView):
    """
    Base class for generic views onto a model instance.
    """
    pk_url_kwarg = 'pk'  # Not provided in Django 1.3
    slug_url_kwarg = 'slug'  # Not provided in Django 1.3
    def get_object(self):
        """
        Override default to add support for object-level permissions.
        """
        obj = super(SingleObjectBaseView, self).get_object()
        if not self.has_permission(self.request, obj):
            self.permission_denied(self.request)
        return obj
### Concrete view classes that provide method handlers ###
### by composing the mixin classes with a base view.   ###
class ListAPIView(mixins.ListModelMixin,
                  MultipleObjectBaseView):
    """
    Concrete view for listing a queryset.
    """
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
class ListCreateAPIView(mixins.ListModelMixin,
                        mixins.CreateModelMixin,
                        MultipleObjectBaseView):
    """
    Concrete view for listing a queryset or creating a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
class RetrieveAPIView(mixins.RetrieveModelMixin,
                      SingleObjectBaseView):
    """
    Concrete view for retrieving a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
                             mixins.DestroyModelMixin,
                             SingleObjectBaseView):
    """
    Concrete view for retrieving or deleting a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
                                   mixins.UpdateModelMixin,
                                   mixins.DestroyModelMixin,
                                   SingleObjectBaseView):
    """
    Concrete view for retrieving, updating or deleting a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
 |