This repository has been archived by the owner on May 20, 2024. It is now read-only.
/
api.py
169 lines (143 loc) · 5.22 KB
/
api.py
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
157
158
159
160
161
162
163
164
165
166
167
168
169
from django.dispatch import Signal
from rest_framework import filters
from rest_framework import mixins
from rest_framework import viewsets
from rest_framework.decorators import detail_route
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import GenericViewSet
from foodsaving.stores.filters import PickupDatesFilter, PickupDateSeriesFilter
from foodsaving.stores.permissions import (
IsUpcoming, HasNotJoinedPickupDate, HasJoinedPickupDate, IsEmptyPickupDate,
IsNotFull)
from foodsaving.stores.serializers import (
StoreSerializer, PickupDateSerializer, PickupDateSeriesSerializer,
PickupDateJoinSerializer, PickupDateLeaveSerializer, FeedbackSerializer)
from foodsaving.stores.models import (
Store as StoreModel,
PickupDate as PickupDateModel,
PickupDateSeries as PickupDateSeriesModel,
Feedback as FeedbackModel
)
from foodsaving.utils.mixins import PartialUpdateModelMixin
pre_pickup_delete = Signal()
pre_series_delete = Signal()
post_store_delete = Signal()
class StoreViewSet(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
PartialUpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet
):
"""
Stores
# Query parameters
- `?group` - filter by store group id
- `?search` - search in name and description
"""
serializer_class = StoreSerializer
queryset = StoreModel.objects.filter(deleted=False)
filter_fields = ('group', 'name')
filter_backends = (filters.SearchFilter, filters.DjangoFilterBackend)
search_fields = ('name', 'description')
permission_classes = (IsAuthenticated,)
def get_queryset(self):
return self.queryset.filter(group__members=self.request.user)
def perform_destroy(self, store):
store.deleted = True
store.save()
post_store_delete.send(
sender=self.__class__,
group=store.group,
store=store,
user=self.request.user,
)
# implicit action: delete all pickups and series, but don't send out signals for them
PickupDateModel.objects.filter(store=store).delete()
PickupDateSeriesModel.objects.filter(store=store).delete()
class FeedbackViewSet(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet
):
serializer_class = FeedbackSerializer
queryset = FeedbackModel.objects.all()
permission_classes = (IsAuthenticated,)
def get_queryset(self):
return self.queryset.filter(about__store__group__members=self.request.user)
class PickupDateSeriesViewSet(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
PartialUpdateModelMixin,
mixins.ListModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet
):
serializer_class = PickupDateSeriesSerializer
queryset = PickupDateSeriesModel.objects
filter_backends = (filters.DjangoFilterBackend,)
filter_class = PickupDateSeriesFilter
permission_classes = (IsAuthenticated,)
def get_queryset(self):
return self.queryset.filter(store__group__members=self.request.user)
def perform_destroy(self, series):
pre_series_delete.send(
sender=self.__class__,
group=series.store.group,
store=series.store,
user=self.request.user,
)
super().perform_destroy(series)
class PickupDateViewSet(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
PartialUpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet
):
"""
Pickup Dates
# Query parameters
- `?series` - filter by pickup date series id
- `?store` - filter by store id
- `?group` - filter by group id
- `?date_0=<from_date>`&`date_1=<to_date>` - filter by date, can also either give date_0 or date_1
"""
serializer_class = PickupDateSerializer
queryset = PickupDateModel.objects.filter(deleted=False)
filter_backends = (filters.DjangoFilterBackend,)
filter_class = PickupDatesFilter
permission_classes = (IsAuthenticated, IsUpcoming)
def get_permissions(self):
if self.action == 'destroy':
self.permission_classes = (IsAuthenticated, IsUpcoming, IsEmptyPickupDate,)
return super().get_permissions()
def get_queryset(self):
return self.queryset.filter(store__group__members=self.request.user)
def perform_destroy(self, pickup):
# set deleted flag to make the pickup date invisible
pickup.deleted = True
pre_pickup_delete.send(
sender=self.__class__,
group=pickup.store.group,
store=pickup.store,
user=self.request.user
)
pickup.save()
@detail_route(
methods=['POST'],
permission_classes=(IsAuthenticated, IsUpcoming, HasNotJoinedPickupDate, IsNotFull),
serializer_class=PickupDateJoinSerializer
)
def add(self, request, pk=None):
return self.partial_update(request)
@detail_route(
methods=['POST'],
permission_classes=(IsAuthenticated, IsUpcoming, HasJoinedPickupDate),
serializer_class=PickupDateLeaveSerializer
)
def remove(self, request, pk=None):
return self.partial_update(request)