From 8774f440b6d08aee19b6bcaa971c1179df17d9b4 Mon Sep 17 00:00:00 2001
From: Ernesto Rico Schmidt <ernesto@helsinki.at>
Date: Fri, 20 Nov 2020 15:11:48 -0400
Subject: [PATCH] Remove deprecated views & clean-up code

---
 program/urls.py  |  27 +----
 program/views.py | 254 +++--------------------------------------------
 2 files changed, 16 insertions(+), 265 deletions(-)

diff --git a/program/urls.py b/program/urls.py
index 54c8b31c..cc1dac0a 100644
--- a/program/urls.py
+++ b/program/urls.py
@@ -1,31 +1,12 @@
-# -*- coding: utf-8 -*-
+import os
 
 from django.conf import settings
 from django.conf.urls import url
-from django.views.decorators.cache import cache_page
 from django.views.static import serve
-from .import views
-
-import os
 
 PROGRAM_SITE_MEDIA = os.path.join(os.path.dirname(__file__), '../site_media')
 
-urlpatterns = [
-    url(r'^calendar/?$', views.CalendarView.as_view()),
-    url(r'^today/?$', views.DayScheduleView.as_view()),
-    url(r'^week/?$', views.WeekScheduleView.as_view()),
-    url(r'^(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/?$', views.DayScheduleView.as_view()),
-    url(r'^(?P<year>\d{4})/(?P<week>\d{1,2})/?$', views.WeekScheduleView.as_view()),
-    url(r'^current_box/?$', cache_page(60)(views.CurrentShowBoxView.as_view())),
-    url(r'^hosts/?$', views.HostListView.as_view()),
-    url(r'^hosts/(?P<pk>\d+)/?$', views.HostDetailView.as_view(), name='host-detail'),
-    url(r'^tips/?$', views.RecommendationsListView.as_view()),
-    url(r'^tips_box/?$', views.RecommendationsBoxView.as_view()),
-    url(r'^shows/?$', views.ShowListView.as_view()),
-    url(r'^shows/(?P<slug>[\w-]+)/?$', views.ShowDetailView.as_view(), name='show-detail'),
-    url(r'^(?P<pk>\d+)/?$', views.TimeSlotDetailView.as_view(), name='timeslot-detail'),
-    url(r'^styles.css$', views.StylesView.as_view())
-]
-
 if settings.DEBUG:
-    urlpatterns.append(url(r'^static/(?P<path>.*)$', serve, {'document_root': PROGRAM_SITE_MEDIA}))
\ No newline at end of file
+    urlpatterns = [url(r'^static/(?P<path>.*)$', serve, {'document_root': PROGRAM_SITE_MEDIA})]
+else:
+    urlpatterns = []
diff --git a/program/views.py b/program/views.py
index 5a6eb544..ad24aad2 100644
--- a/program/views.py
+++ b/program/views.py
@@ -7,9 +7,6 @@ from django.http import HttpResponse
 from django.shortcuts import get_object_or_404
 from django.utils import timezone
 from django.utils.translation import ugettext_lazy as _
-from django.views.generic.base import TemplateView
-from django.views.generic.detail import DetailView
-from django.views.generic.list import ListView
 from rest_framework import permissions, status, viewsets
 from rest_framework.pagination import LimitOffsetPagination
 from rest_framework.response import Response
@@ -18,201 +15,7 @@ from program.models import Type, MusicFocus, Language, Note, Show, Category, Fun
 from program.serializers import TypeSerializer, LanguageSerializer, MusicFocusSerializer, NoteSerializer, ShowSerializer, \
     ScheduleSerializer, CategorySerializer, FundingCategorySerializer, TopicSerializer, TimeSlotSerializer, HostSerializer, \
     UserSerializer
-from program.utils import tofirstdayinisoweek, get_cached_shows
-
-
-# Deprecated
-class CalendarView(TemplateView):
-    template_name = 'calendar.html'
-
-
-# Deprecated
-class HostListView(ListView):
-    context_object_name = 'host_list'
-    queryset = Host.objects.filter(Q(is_active=True) | Q(shows__schedules__until__gt=timezone.now())).distinct()
-    template_name = 'host_list.html'
-
-
-# Deprecated
-class HostDetailView(DetailView):
-    context_object_name = 'host'
-    queryset = Host.objects.all()
-    template_name = 'host_detail.html'
-
-
-# Deprecated
-class ShowListView(ListView):
-    context_object_name = 'show_list'
-    template_name = 'show_list.html'
-
-    def get_queryset(self):
-        queryset = Show.objects.filter(schedules__until__gt=date.today()).exclude(id=1).distinct()
-        if 'type' in self.request.GET:
-            type = get_object_or_404(Type, slug=self.request.GET['type'])
-            queryset = queryset.filter(type=type)
-        elif 'musicfocus' in self.request.GET:
-            musicfocus = get_object_or_404(MusicFocus, slug=self.request.GET['musicfocus'])
-            queryset = queryset.filter(musicfocus=musicfocus)
-        elif 'category' in self.request.GET:
-            category = get_object_or_404(Category, slug=self.request.GET['category'])
-            queryset = queryset.filter(category=category)
-        elif 'topic' in self.request.GET:
-            topic = get_object_or_404(Topic, slug=self.request.GET['topic'])
-            queryset = queryset.filter(topic=topic)
-        elif 'fundingcategory' in self.request.GET:
-            fundingcategory = get_object_or_404(FundingCategory, slug=self.request.GET['fundingcategory'])
-            queryset = queryset.filter(fundingcategory=fundingcategory)
-
-
-        return queryset
-
-
-# Deprecated
-class ShowDetailView(DetailView):
-    queryset = Show.objects.all().exclude(id=1)
-    template_name = 'show_detail.html'
-
-
-# Deprecated
-class TimeSlotDetailView(DetailView):
-    queryset = TimeSlot.objects.all()
-    template_name = 'timeslot_detail.html'
-
-
-# Deprecated
-class RecommendationsListView(ListView):
-    context_object_name = 'recommendation_list'
-    template_name = 'recommendation_list.html'
-
-    now = timezone.now()
-    end = now + timedelta(weeks=1)
-
-    queryset = TimeSlot.objects.filter(Q(note__isnull=False, note__status=1,
-                                         start__range=(now, end)) |
-                                       Q(show__type__slug='sondersendung',
-                                         start__range=(now, end))).order_by('start')[:20]
-
-
-# Deprecated
-class RecommendationsBoxView(RecommendationsListView):
-    template_name = 'boxes/recommendation.html'
-
-
-# Deprecated
-class DayScheduleView(TemplateView):
-    template_name = 'day_schedule.html'
-
-    def get_context_data(self, **kwargs):
-        year = self.kwargs.get('year', None)
-        month = self.kwargs.get('month', None)
-        day = self.kwargs.get('day', None)
-
-        if year is None and month is None and day is None:
-            today = datetime.combine(date.today(), time(6, 0))
-        else:
-            today = datetime.strptime('%s__%s__%s__06__00' % (year, month, day), '%Y__%m__%d__%H__%M')
-
-        tomorrow = today + timedelta(days=1)
-
-        context = super(DayScheduleView, self).get_context_data(**kwargs)
-        context['day'] = today
-        context['recommendations'] = Note.objects.filter(status=1, timeslot__start__range=(today, tomorrow))
-        context['default_show'] = Show.objects.get(pk=1)
-
-        timeslots = TimeSlot.objects.get_day_timeslots(today)
-
-        if 'type' in self.request.GET:
-            type = get_object_or_404(Type, slug=self.request.GET['type'])
-            context['timeslots'] = timeslots.filter(show__type=type)
-        elif 'musicfocus' in self.request.GET:
-            musicfocus = get_object_or_404(MusicFocus, slug=self.request.GET['musicfocus'])
-            context['timeslots'] = timeslots.filter(show__musicfocus=musicfocus)
-        elif 'category' in self.request.GET:
-            category = get_object_or_404(Category, slug=self.request.GET['category'])
-            context['timeslots'] = timeslots.filter(show__category=category)
-        elif 'topic' in self.request.GET:
-            topic = get_object_or_404(Topic, slug=self.request.GET['topic'])
-            context['topic'] = timeslots.filter(show__topic=topic)
-        else:
-            context['timeslots'] = timeslots
-        return context
-
-
-# Deprecated
-class CurrentShowBoxView(TemplateView):
-    context_object_name = 'recommendation_list'
-    template_name = 'boxes/current.html'
-
-    def get_context_data(self, **kwargs):
-        current_timeslot = TimeSlot.objects.get_or_create_current()
-        previous_timeslot = current_timeslot.get_previous_by_start()
-        next_timeslot = current_timeslot.get_next_by_start()
-        after_next_timeslot = next_timeslot.get_next_by_start()
-
-        context = super(CurrentShowBoxView, self).get_context_data(**kwargs)
-        context['current_timeslot'] = current_timeslot
-        context['previous_timeslot'] = previous_timeslot
-        context['next_timeslot'] = next_timeslot
-        context['after_next_timeslot'] = after_next_timeslot
-        return context
-
-
-# Deprecated
-class WeekScheduleView(TemplateView):
-    template_name = 'week_schedule.html'
-
-    def get_context_data(self, **kwargs):
-        year = self.kwargs.get('year', None)
-        week = self.kwargs.get('week', None)
-
-        if year is None and week is None:
-            year, week = timezone.now().strftime('%G__%V').split('__')
-
-        monday = tofirstdayinisoweek(int(year), int(week))
-        tuesday = monday + timedelta(days=1)
-        wednesday = monday + timedelta(days=2)
-        thursday = monday + timedelta(days=3)
-        friday = monday + timedelta(days=4)
-        saturday = monday + timedelta(days=5)
-        sunday = monday + timedelta(days=6)
-
-        context = super(WeekScheduleView, self).get_context_data()
-        context['monday'] = monday
-        context['tuesday'] = tuesday
-        context['wednesday'] = wednesday
-        context['thursday'] = thursday
-        context['friday'] = friday
-        context['saturday'] = saturday
-        context['sunday'] = sunday
-        context['default_show'] = Show.objects.get(pk=1)
-        context['monday_timeslots'] = TimeSlot.objects.get_day_timeslots(monday)
-        context['tuesday_timeslots'] = TimeSlot.objects.get_day_timeslots(tuesday)
-        context['wednesday_timeslots'] = TimeSlot.objects.get_day_timeslots(wednesday)
-        context['thursday_timeslots'] = TimeSlot.objects.get_day_timeslots(thursday)
-        context['friday_timeslots'] = TimeSlot.objects.get_day_timeslots(friday)
-        context['saturday_timeslots'] = TimeSlot.objects.get_day_timeslots(saturday)
-        context['sunday_timeslots'] = TimeSlot.objects.get_day_timeslots(sunday)
-        context['last_w'] = datetime.strftime(monday - timedelta(days=7), '%G/%V')
-        context['cur_w'] = datetime.strftime(monday, '%G/%V')
-        context['next_w1'] = datetime.strftime(monday + timedelta(days=7), '%G/%V')
-        context['next_w2'] = datetime.strftime(monday + timedelta(days=14), '%G/%V')
-        context['next_w3'] = datetime.strftime(monday + timedelta(days=21), '%G/%V')
-        context['next_w4'] = datetime.strftime(monday + timedelta(days=28), '%G/%V')
-        return context
-
-
-# Deprecated
-class StylesView(TemplateView):
-    template_name = 'styles.css'
-    content_type = 'text/css'
-
-    def get_context_data(self, **kwargs):
-        context = super(StylesView, self).get_context_data(**kwargs)
-        context['types'] = Type.objects.filter(is_active=True)
-        context['musicfocus'] = MusicFocus.objects.all()
-        context['category'] = Category.objects.all()
-        context['topic'] = Topic.objects.all()
-        return context
+from program.utils import get_cached_shows
 
 
 # Deprecated
@@ -259,14 +62,14 @@ def json_playout(request):
     if request.GET.get('start') == None:
         start = datetime.combine(date.today(), time(0, 0))
     else:
-        start = datetime.combine( datetime.strptime(request.GET.get('start'), '%Y-%m-%d').date(), time(0, 0))
+        start = datetime.combine(datetime.strptime(request.GET.get('start'), '%Y-%m-%d').date(), time(0, 0))
 
     if request.GET.get('end') == None:
         # If no end was given, return the next week
         timeslots = TimeSlot.objects.get_7d_timeslots(start).select_related('schedule').select_related('show')
     else:
         # Otherwise return the given timerange
-        end = datetime.combine( datetime.strptime(request.GET.get('end'), '%Y-%m-%d').date(), time(23, 59))
+        end = datetime.combine(datetime.strptime(request.GET.get('end'), '%Y-%m-%d').date(), time(23, 59))
         timeslots = TimeSlot.objects.get_timerange_timeslots(start, end).select_related('schedule').select_related('show')
 
     schedule = []
@@ -295,7 +98,7 @@ def json_playout(request):
             'id': ts.id,
             'start': ts.start.strftime('%Y-%m-%dT%H:%M:%S'),
             'end': ts.end.strftime('%Y-%m-%dT%H:%M:%S'),
-            'title': ts.show.name + is_repetition, # For JS Calendar
+            'title': ts.show.name + is_repetition,  # For JS Calendar
             'automation-id': -1,
             'schedule_id': ts.schedule.id,
             'is_repetition': ts.is_repetition,
@@ -311,7 +114,7 @@ def json_playout(request):
             'show_musicfocus': musicfocus,
             'show_languages': languages,
             'show_fundingcategory': fdcategory,
-            'station_fallback_id': STATION_FALLBACK_ID, # TODO: Find a better way than getting it from the settings
+            'station_fallback_id': STATION_FALLBACK_ID,  # TODO: Find a better way than getting it from the settings
             'memo': ts.memo,
             'className': classname,
         }
@@ -352,8 +155,6 @@ def json_timeslots_specials(request):
                         content_type="application/json; charset=utf-8")
 
 
-
-
 ####################################################################
 # REST API View Sets
 ####################################################################
@@ -378,13 +179,11 @@ class APIUserViewSet(viewsets.ModelViewSet):
 
         return User.objects.filter(pk=self.request.user.id)
 
-
     def list(self, request):
         users = self.get_queryset()
         serializer = UserSerializer(users, many=True)
         return Response(serializer.data)
 
-
     def retrieve(self, request, pk=None):
         """Returns a single user"""
 
@@ -396,7 +195,6 @@ class APIUserViewSet(viewsets.ModelViewSet):
         serializer = UserSerializer(user)
         return Response(serializer.data)
 
-
     def create(self, request, pk=None):
         """
         Create a User
@@ -414,7 +212,6 @@ class APIUserViewSet(viewsets.ModelViewSet):
 
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
-
     def update(self, request, pk=None):
 
         serializer = UserSerializer(data=request.data)
@@ -423,7 +220,7 @@ class APIUserViewSet(viewsets.ModelViewSet):
             return Response(serializer.initial_data, status=status.HTTP_401_UNAUTHORIZED)
 
         user = get_object_or_404(User, pk=pk)
-        serializer = UserSerializer(user, data=request.data, context={ 'user': request.user })
+        serializer = UserSerializer(user, data=request.data, context={'user': request.user})
 
         if serializer.is_valid():
             serializer.save();
@@ -431,13 +228,11 @@ class APIUserViewSet(viewsets.ModelViewSet):
 
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
-
     def destroy(self, request, pk=None):
         """Deleting users is prohibited: Set 'is_active' to False instead"""
         return Response(status=status.HTTP_401_UNAUTHORIZED)
 
 
-
 class APIShowViewSet(viewsets.ModelViewSet):
     """
     /api/v1/shows/                                             Returns all shows (GET, POST)
@@ -479,17 +274,17 @@ class APIShowViewSet(viewsets.ModelViewSet):
             # For single dates we test if there'll be one in the future (and ignore the until date)
             # TODO: Really consider dstart? (=currently active, not just upcoming ones)
             # Add limit for future?
-            show_ids = Schedule.objects.filter( Q(rrule_id__gt=1,dstart__lte=date.today(),until__gte=date.today()) |
-                                                 Q(rrule_id=1,dstart__gte=date.today())
+            show_ids = Schedule.objects.filter(Q(rrule_id__gt=1, dstart__lte=date.today(), until__gte=date.today()) |
+                                               Q(rrule_id=1, dstart__gte=date.today())
                                                ).distinct().values_list('show_id', flat=True)
 
             # Filter active shows based on timeslots as well as on the is_active flag
             # Even if there are future timeslots but is_active=True the show will be considered as inactive
-            shows = Show.objects.filter(id__in=show_ids,is_active=True)
+            shows = Show.objects.filter(id__in=show_ids, is_active=True)
 
         if self.request.GET.get('active') == 'false':
             '''Return all shows except those which are running'''
-            shows = Show.objects.exclude(id__in=show_ids,is_active=True)
+            shows = Show.objects.exclude(id__in=show_ids, is_active=True)
 
         if self.request.GET.get('public') == 'true':
             '''Return all public shows'''
@@ -509,7 +304,6 @@ class APIShowViewSet(viewsets.ModelViewSet):
 
         return shows
 
-
     def create(self, request, pk=None):
         """
         Create a show
@@ -527,7 +321,6 @@ class APIShowViewSet(viewsets.ModelViewSet):
 
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
-
     def retrieve(self, request, pk=None):
         """Returns a single show"""
         show = get_object_or_404(Show, pk=pk)
@@ -535,7 +328,6 @@ class APIShowViewSet(viewsets.ModelViewSet):
 
         return Response(serializer.data)
 
-
     def update(self, request, pk=None):
         """
         Update a show
@@ -546,7 +338,7 @@ class APIShowViewSet(viewsets.ModelViewSet):
             return Response(status=status.HTTP_401_UNAUTHORIZED)
 
         show = get_object_or_404(Show, pk=pk)
-        serializer = ShowSerializer(show, data=request.data, context={ 'user': request.user })
+        serializer = ShowSerializer(show, data=request.data, context={'user': request.user})
 
         if serializer.is_valid():
             # Common users mustn't edit the show's name
@@ -557,7 +349,6 @@ class APIShowViewSet(viewsets.ModelViewSet):
 
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
-
     def destroy(self, request, pk=None):
         """
         Delete a show
@@ -599,14 +390,12 @@ class APIScheduleViewSet(viewsets.ModelViewSet):
 
         return Schedule.objects.all()
 
-
     def list(self, request, show_pk=None, pk=None):
         """List Schedules of a show"""
         schedules = self.get_queryset()
         serializer = ScheduleSerializer(schedules, many=True)
         return Response(serializer.data)
 
-
     def retrieve(self, request, pk=None, show_pk=None):
 
         if show_pk != None:
@@ -617,7 +406,6 @@ class APIScheduleViewSet(viewsets.ModelViewSet):
         serializer = ScheduleSerializer(schedule)
         return Response(serializer.data)
 
-
     def create(self, request, pk=None, show_pk=None):
         """
         Create a schedule, generate timeslots, test for collisions and resolve them including notes
@@ -648,7 +436,6 @@ class APIScheduleViewSet(viewsets.ModelViewSet):
         # Otherwise return conflicts
         return Response(resolution)
 
-
     def update(self, request, pk=None, show_pk=None):
         """
         Update a schedule, generate timeslots, test for collisions and resolve them including notes
@@ -681,7 +468,6 @@ class APIScheduleViewSet(viewsets.ModelViewSet):
         # Otherwise return conflicts
         return Response(resolution)
 
-
     def destroy(self, request, pk=None, show_pk=None):
         """
         Delete a schedule
@@ -698,8 +484,6 @@ class APIScheduleViewSet(viewsets.ModelViewSet):
         return Response(status=status.HTTP_204_NO_CONTENT)
 
 
-
-
 class APITimeSlotViewSet(viewsets.ModelViewSet):
     """
     /api/v1/timeslots                                                     Returns timeslots of the next 60 days (GET) - Timeslots may only be added by creating/updating a schedule
@@ -759,7 +543,6 @@ class APITimeSlotViewSet(viewsets.ModelViewSet):
         else:
             return TimeSlot.objects.filter(start__gte=start, end__lte=end).order_by('start')
 
-
     def retrieve(self, request, pk=None, schedule_pk=None, show_pk=None):
 
         if show_pk != None:
@@ -770,7 +553,6 @@ class APITimeSlotViewSet(viewsets.ModelViewSet):
         serializer = TimeSlotSerializer(timeslot)
         return Response(serializer.data)
 
-
     def create(self, request):
         """
         Timeslots may only be created by adding/updating schedules
@@ -778,7 +560,6 @@ class APITimeSlotViewSet(viewsets.ModelViewSet):
         """
         return Response(status=status.HTTP_401_UNAUTHORIZED)
 
-
     def update(self, request, pk=None, schedule_pk=None, show_pk=None):
         """Link a playlist_id to a timeslot"""
 
@@ -805,7 +586,6 @@ class APITimeSlotViewSet(viewsets.ModelViewSet):
 
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
-
     def destroy(self, request, pk=None, schedule_pk=None, show_pk=None):
         """
         Delete a timeslot
@@ -825,7 +605,6 @@ class APITimeSlotViewSet(viewsets.ModelViewSet):
         return Response(status=status.HTTP_204_NO_CONTENT)
 
 
-
 class APINoteViewSet(viewsets.ModelViewSet):
     """
     /api/v1/notes/                                  Returns all notes (GET) - POST not allowed at this level
@@ -904,7 +683,6 @@ class APINoteViewSet(viewsets.ModelViewSet):
 
         return notes
 
-
     def create(self, request, pk=None, timeslot_pk=None, schedule_pk=None, show_pk=None):
         """Create a note"""
 
@@ -915,7 +693,7 @@ class APINoteViewSet(viewsets.ModelViewSet):
         if not Show.is_editable(self, show_pk):
             return Response(status=status.HTTP_401_UNAUTHORIZED)
 
-        serializer = NoteSerializer(data=request.data, context={ 'user_id': request.user.id })
+        serializer = NoteSerializer(data=request.data, context={'user_id': request.user.id})
 
         if serializer.is_valid():
 
@@ -928,7 +706,6 @@ class APINoteViewSet(viewsets.ModelViewSet):
 
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
-
     def retrieve(self, request, pk=None, timeslot_pk=None, schedule_pk=None, show_pk=None):
         """
         Returns a single note
@@ -968,7 +745,6 @@ class APINoteViewSet(viewsets.ModelViewSet):
         serializer = NoteSerializer(note)
         return Response(serializer.data)
 
-
     def update(self, request, pk=None, show_pk=None, schedule_pk=None, timeslot_pk=None):
 
         # Allow PUT only when calling /shows/1/schedules/1/timeslots/1/note/1
@@ -994,7 +770,6 @@ class APINoteViewSet(viewsets.ModelViewSet):
 
         return Response(status=status.HTTP_400_BAD_REQUEST)
 
-
     def destroy(self, request, pk=None, show_pk=None, schedule_pk=None, timeslot_pk=None):
         # Allow DELETE only when calling /shows/1/schedules/1/timeslots/1/note/1
         if show_pk == None or schedule_pk == None or timeslot_pk == None:
@@ -1020,7 +795,6 @@ class APICategoryViewSet(viewsets.ModelViewSet):
     serializer_class = CategorySerializer
     permission_classes = [permissions.DjangoModelPermissionsOrAnonReadOnly]
 
-
     def get_queryset(self):
         '''Filters'''
 
@@ -1080,7 +854,6 @@ class APITopicViewSet(viewsets.ModelViewSet):
         return Topic.objects.all()
 
 
-
 class APIMusicFocusViewSet(viewsets.ModelViewSet):
     """
     /api/v1/musicfocus/              Returns all musicfocuses (GET, POST)
@@ -1105,7 +878,6 @@ class APIMusicFocusViewSet(viewsets.ModelViewSet):
         return MusicFocus.objects.all()
 
 
-
 class APIFundingCategoryViewSet(viewsets.ModelViewSet):
     """
     /api/v1/fundingcategories/              Returns all fundingcategories (GET, POST)
@@ -1130,7 +902,6 @@ class APIFundingCategoryViewSet(viewsets.ModelViewSet):
         return FundingCategory.objects.all()
 
 
-
 class APILanguageViewSet(viewsets.ModelViewSet):
     """
     /api/v1/languages/              Returns all languages (GET, POST)
@@ -1155,7 +926,6 @@ class APILanguageViewSet(viewsets.ModelViewSet):
         return Language.objects.all()
 
 
-
 class APIHostViewSet(viewsets.ModelViewSet):
     """
     /api/v1/hosts/              Returns all hosts (GET, POST)
-- 
GitLab