From a8372dc6d2d60f193b2599f5ca07275576ccd087 Mon Sep 17 00:00:00 2001 From: "Danilo G. Baio" Date: Sun, 16 Aug 2020 18:17:56 -0300 Subject: [PATCH] Add REST framework Initially read only and with simple filters --- ports/serializers.py | 55 +++++++++++++++++++++++++++++++++ ports/templates/ports/base.html | 3 ++ ports/urls.py | 9 +++++- ports/views.py | 32 +++++++++++++++++++ portsfallout/settings_dev.py | 6 ++++ requirements.txt | 1 + 6 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 ports/serializers.py diff --git a/ports/serializers.py b/ports/serializers.py new file mode 100644 index 0000000..d7f0c7a --- /dev/null +++ b/ports/serializers.py @@ -0,0 +1,55 @@ +# Copyright (c) 2020 Danilo G. Baio +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from ports.models import Category, Port, Fallout +from rest_framework import serializers + + +class CategorySerializer(serializers.HyperlinkedModelSerializer): + url = serializers.HyperlinkedIdentityField( + view_name="ports:category-detail", + ) + class Meta: + model = Category + fields = '__all__' + + +class PortSerializer(serializers.HyperlinkedModelSerializer): + categories = CategorySerializer(many=True, read_only=True) + url = serializers.HyperlinkedIdentityField( + view_name="ports:port-detail", + ) + class Meta: + model = Port + fields = '__all__' + + +class FalloutSerializer(serializers.HyperlinkedModelSerializer): + port = PortSerializer(many=False, read_only=True) + url = serializers.HyperlinkedIdentityField( + view_name="ports:fallout-detail", + ) + class Meta: + model = Fallout + fields = '__all__' + diff --git a/ports/templates/ports/base.html b/ports/templates/ports/base.html index dc30fc8..ff9f54f 100644 --- a/ports/templates/ports/base.html +++ b/ports/templates/ports/base.html @@ -23,6 +23,9 @@ + diff --git a/ports/urls.py b/ports/urls.py index 83b399b..dd42752 100644 --- a/ports/urls.py +++ b/ports/urls.py @@ -23,8 +23,14 @@ """ports URL Configuration""" -from django.urls import path +from django.urls import include, path from ports import views +from rest_framework import routers + +router = routers.DefaultRouter() +router.register(r'category', views.CategoryViewSet) +router.register(r'port', views.PortViewSet) +router.register(r'fallout', views.FalloutViewSet) # TEMPLATE TAGGING app_name = 'ports' @@ -36,4 +42,5 @@ path('port', views.PortListView.as_view(), name='list'), path('port//', views.PortDetailView.as_view(), name='detail'), path('about', views.about, name='about'), + path('api/', include(router.urls)), ] diff --git a/ports/views.py b/ports/views.py index 5b78447..a2b3eb3 100644 --- a/ports/views.py +++ b/ports/views.py @@ -25,6 +25,8 @@ from django.views.generic import View, TemplateView, ListView, DetailView from django.db.models import Count, Q from ports.models import Port, Category, Fallout +from ports.serializers import CategorySerializer, PortSerializer, FalloutSerializer +from rest_framework import filters, viewsets from datetime import date, timedelta @@ -137,3 +139,33 @@ def about(request): context_dict = {'navbar_about':'active'} return render(request, 'ports/about.html', context_dict) + +class CategoryViewSet(viewsets.ReadOnlyModelViewSet): + """ + API endpoint for Categories. + """ + search_fields = ['name'] + filter_backends = (filters.SearchFilter,) + queryset = Category.objects.all().order_by('name') + serializer_class = CategorySerializer + + +class PortViewSet(viewsets.ReadOnlyModelViewSet): + """ + API endpoint for Port's. + """ + search_fields = ['origin', 'maintainer'] + filter_backends = (filters.SearchFilter,) + queryset = Port.objects.all().order_by('origin') + serializer_class = PortSerializer + + +class FalloutViewSet(viewsets.ReadOnlyModelViewSet): + """ + API endpoint for Fallout's. + """ + search_fields = ['maintainer', 'port__origin', 'env', 'category'] + filter_backends = (filters.SearchFilter,) + queryset = Fallout.objects.all().order_by('-date') + serializer_class = FalloutSerializer + diff --git a/portsfallout/settings_dev.py b/portsfallout/settings_dev.py index 42983d4..b558b72 100644 --- a/portsfallout/settings_dev.py +++ b/portsfallout/settings_dev.py @@ -61,6 +61,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'rest_framework', 'debug_toolbar', 'bootstrap_pagination', 'ports', @@ -154,3 +155,8 @@ INTERNAL_IPS = [ '127.0.0.1', ] + +REST_FRAMEWORK = { + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', + 'PAGE_SIZE': 50 +} diff --git a/requirements.txt b/requirements.txt index 8f944e4..b551caa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ django django-bootstrap-pagination requests scrapy +djangorestframework