views.py 6.19 KB
Newer Older
1
"""
2
3
api/views.py

4
5
Rest Framework Class Views
"""
6
7
8
9
# Future Imports
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

10
11
12
# Python std. lib. imports
import datetime

13
# App Imports
David Haynes's avatar
David Haynes committed
14
from .models import Facility, OpenTime, Category, Schedule, Location, Alert
15
from .serializers import (CategorySerializer, FacilitySerializer,
David Haynes's avatar
David Haynes committed
16
                          ScheduleSerializer, OpenTimeSerializer,
David Haynes's avatar
David Haynes committed
17
                          LocationSerializer, AlertSerializer)
18

19
# Other Imports
David Haynes's avatar
David Haynes committed
20
21
from rest_framework import viewsets, filters
from django_filters.rest_framework import DjangoFilterBackend
22

David Haynes's avatar
David Haynes committed
23
24
class AlertViewSet(viewsets.ReadOnlyModelViewSet):
    """
David Haynes's avatar
David Haynes committed
25
    Return all Alert objects.
David Haynes's avatar
David Haynes committed
26
27
28
    """
    serializer_class = AlertSerializer

David Haynes's avatar
David Haynes committed
29
    def get_queryset(self):
30
31
32
33
        """
        Handle incoming GET requests and enumerate objects that get returned by
        the API.
        """
David Haynes's avatar
David Haynes committed
34
35
        return Alert.objects.all()

36
class CategoryViewSet(viewsets.ReadOnlyModelViewSet):
37
    """
David Haynes's avatar
David Haynes committed
38
    Return all Category objects.
39
    """
40
41
    serializer_class = CategorySerializer

David Haynes's avatar
David Haynes committed
42
    def get_queryset(self):
43
44
45
46
        """
        Handle incoming GET requests and enumerate objects that get returned by
        the API.
        """
David Haynes's avatar
David Haynes committed
47
48
        return Category.objects.all()

David Haynes's avatar
David Haynes committed
49
50
class LocationViewSet(viewsets.ReadOnlyModelViewSet):
    """
David Haynes's avatar
David Haynes committed
51
    Return all Location objects.
David Haynes's avatar
David Haynes committed
52
53
54
    """
    serializer_class = LocationSerializer

David Haynes's avatar
David Haynes committed
55
    def get_queryset(self):
56
57
58
59
        """
        Handle incoming GET requests and enumerate objects that get returned by
        the API.
        """
David Haynes's avatar
David Haynes committed
60
61
        return Location.objects.all()

62
class FacilityViewSet(viewsets.ReadOnlyModelViewSet):
63
    """
64
65
66
67
68
    A Facility is some type of establishment that has a schedule of open hours and a location that serves a specific purpose that can be categorized.

    GET /api/facilities/
    Return all Facility objects. We additionally filter out stale special_schedules to reduce client side calculations.

David Haynes's avatar
David Haynes committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    Built-in query parameters:

    GET /api/facilities/?search=
    Query parameter that returns objects that match a keyword provided in the search.

    GET /api/facilities/?ordering=
    Query parameter that orders the returned objects based on the provided field to order by.

    Additionally, you can query against any field you like:

    ie.
    GET /api/facilities/?facility_name=Southside
    will return the Facility object that has "Southside" as its name.

    Custom query parameters:

85
86
    GET /api/facilities/?open_now
    Query parameter that only returns open Facility objects.
David Haynes's avatar
David Haynes committed
87
88
89

    GET /api/facilities/?closed_now
    Query parameter that only returns closed Facility objects.
90
    """
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    FILTER_FIELDS = (
        # Facility fields
        'facility_name',
        'tapingo_url',
        'facility_product_tags__name',
        # Category fields
        'facility_category__name',
        # Location fields
        'facility_location__building',
        'facility_location__address',
        'facility_location__on_campus',
        # Schedule fields
        'main_schedule__name',
        'main_schedule__valid_start',
        'main_schedule__valid_end',
        'special_schedules__name',
        'special_schedules__valid_start',
        'special_schedules__valid_end',
    )

David Haynes's avatar
David Haynes committed
111
    # Associate a serializer with the ViewSet
112
    serializer_class = FacilitySerializer
113
114
115
116
117
    filter_backends = (filters.SearchFilter, DjangoFilterBackend,
                       filters.OrderingFilter, )
    search_fields = FILTER_FIELDS
    ordering_fields = FILTER_FIELDS
    filter_fields = FILTER_FIELDS
118

119
    def get_queryset(self):
120
        """
121
122
        Handle incoming GET requests and enumerate objects that get returned by
        the API.
123
        """
David Haynes's avatar
David Haynes committed
124
        # Define ?open_now
David Haynes's avatar
David Haynes committed
125
        open_now = self.request.query_params.get('open_now', None)
David Haynes's avatar
David Haynes committed
126
127
128
        # Define ?closed_now
        closed_now = self.request.query_params.get('closed_now', None)
        if open_now is not None or closed_now is not None:
129
130
131
132
133
134
135
136
            # List of all open facilities
            open_facilities = []
            for facility in Facility.objects.all():
                if facility.is_open():
                    # Append the primary key
                    open_facilities.append(facility.pk)
            # Return all Facility objects with the primary keys located in the
            # open_facilities list
David Haynes's avatar
David Haynes committed
137
138
139
140
141
142
            if open_now:
                return Facility.objects.filter(pk__in=open_facilities)
            # Return all Facility objects with the primary keys not located in
            # the open_facilities list
            elif closed_now:
                return Facility.objects.exclude(pk__in=open_facilities)
143
        # Default behavior
144
        else:
145
146
147
            for facility in Facility.objects.all():
                # Remove all special_schedules that have expired
                facility.clean_special_schedules()
David Haynes's avatar
David Haynes committed
148
            return Facility.objects.all()
149

150
class ScheduleViewSet(viewsets.ModelViewSet):
151
    """
152
153
154
155
    A period of time between two dates that represents the beginning and end of a "schedule" or rather, a collection of open times for a facility.

    GET /api/schedules
    Return all Schedule objects that have not expired. (ie. end_date is before today)
156
    """
157
158
    serializer_class = ScheduleSerializer

David Haynes's avatar
David Haynes committed
159
    def get_queryset(self):
160
161
162
163
164
165
166
167
168
169
170
171
172
173
        """
        Handle incoming GET requests and enumerate objects that get returned by
        the API.
        """
        # List of all schedules that are outdated
        filter_old_schedules = []
        for schedule in Schedule.objects.all():
            if schedule.valid_end and schedule.valid_start:
                # If the schedule ended before today
                if schedule.valid_end < datetime.date.today():
                    # Add it to the list of objects we are excluding
                    filter_old_schedules.append(schedule.pk)
        # Return all Schedule objects that have not expired
        return Schedule.objects.exclude(pk__in=filter_old_schedules)
David Haynes's avatar
David Haynes committed
174

175
class OpenTimeViewSet(viewsets.ModelViewSet):
176
    """
David Haynes's avatar
David Haynes committed
177
    Return all OpenTime objects.
178
    """
179
    serializer_class = OpenTimeSerializer
David Haynes's avatar
David Haynes committed
180
181

    def get_queryset(self):
182
183
184
185
        """
        Handle incoming GET requests and enumerate objects that get returned by
        the API.
        """
186
        return OpenTime.objects.all()