refactor api views inter their respecting apps

This commit is contained in:
Laura Klünder 2016-09-22 12:58:21 +02:00
parent b69dff708e
commit 02cafee6be
12 changed files with 112 additions and 117 deletions

View file

@ -1,26 +0,0 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from shapely.geometry import mapping, shape
from ..mapdata.utils import sort_geojson
class GeometryField(serializers.DictField):
"""
shapely geometry objects serialized using GeoJSON
"""
default_error_messages = {
'invalid': _('Invalid GeoJSON.')
}
def to_representation(self, obj):
geojson = sort_geojson(mapping(obj))
return super().to_representation(geojson)
def to_internal_value(self, data):
geojson = super().to_internal_value(data)
try:
return shape(geojson)
except:
raise ValidationError(_('Invalid GeoJSON.'))

View file

@ -1,63 +0,0 @@
from django.conf import settings
from rest_framework import serializers
from ..editor.hosters import get_hoster_for_package
from ..mapdata.models import Feature, Level, Package, Source
from .fields import GeometryField
from .permissions import can_access_package
class LevelSerializer(serializers.ModelSerializer):
class Meta:
model = Level
fields = ('name', 'altitude', 'package')
class PackageSerializer(serializers.ModelSerializer):
class Meta:
model = Package
fields = ('name', 'home_repo', 'commit_id', 'depends', 'bounds')
def to_representation(self, obj):
result = super().to_representation(obj)
result['public'] = obj.name in settings.PUBLIC_PACKAGES
hoster = get_hoster_for_package(obj)
if 'request' in self.context:
result['access_granted'] = can_access_package(self.context['request'], obj)
if hoster is not None:
result['hoster'] = hoster.name
return result
class SourceSerializer(serializers.ModelSerializer):
class Meta:
model = Source
fields = ('name', 'package', 'bounds')
class FeatureTypeSerializer(serializers.Serializer):
name = serializers.CharField()
title = serializers.CharField()
title_plural = serializers.CharField()
geomtype = serializers.CharField()
color = serializers.CharField()
class FeatureSerializer(serializers.ModelSerializer):
geometry = GeometryField()
class Meta:
model = Feature
fields = ('name', 'package', 'feature_type', 'geometry')
class HosterSerializer(serializers.Serializer):
name = serializers.CharField()
base_url = serializers.CharField()
def to_representation(self, obj):
result = super().to_representation(obj)
result['packages'] = tuple(obj.get_packages().values_list('name', flat=True))
if 'request' in self.context:
result['signed_in'] = obj.is_access_granted(self.context['request'])
return result

View file

@ -1,16 +1,16 @@
from django.conf.urls import include, url
from rest_framework.routers import DefaultRouter
from .views import editor as editor_views
from .views import mapdata as mapdata_views
from ..editor import api as editor_api
from ..mapdata import api as mapdata_api
router = DefaultRouter()
router.register(r'levels', mapdata_views.LevelViewSet)
router.register(r'packages', mapdata_views.PackageViewSet)
router.register(r'sources', mapdata_views.SourceViewSet)
router.register(r'featuretypes', mapdata_views.FeatureTypeViewSet, base_name='featuretype')
router.register(r'features', editor_views.FeatureViewSet)
router.register(r'hosters', editor_views.HosterViewSet, base_name='hoster')
router.register(r'levels', mapdata_api.LevelViewSet)
router.register(r'packages', mapdata_api.PackageViewSet)
router.register(r'sources', mapdata_api.SourceViewSet)
router.register(r'featuretypes', mapdata_api.FeatureTypeViewSet, base_name='featuretype')
router.register(r'features', mapdata_api.FeatureViewSet)
router.register(r'hosters', editor_api.HosterViewSet, base_name='hoster')
urlpatterns = [

View file

@ -1,10 +1,9 @@
from django.http import Http404
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet, ViewSet
from rest_framework.viewsets import ViewSet
from ...editor.hosters import hosters
from ...mapdata.models import Feature
from ..serializers import FeatureSerializer, HosterSerializer
from .hosters import hosters
from .serializers import HosterSerializer
class HosterViewSet(ViewSet):
@ -20,12 +19,3 @@ class HosterViewSet(ViewSet):
raise Http404
serializer = HosterSerializer(hosters[pk], context={'request': request})
return Response(serializer.data)
class FeatureViewSet(ModelViewSet):
"""
Get all Map Features including ones that are only part of the current session
"""
queryset = Feature.objects.all()
serializer_class = FeatureSerializer
lookup_value_regex = '[^/]+'

View file

@ -0,0 +1,14 @@
from rest_framework import serializers
class HosterSerializer(serializers.Serializer):
name = serializers.CharField()
base_url = serializers.CharField()
packages = serializers.SerializerMethodField()
signed_in = serializers.SerializerMethodField()
def get_packages(self, obj):
return tuple(obj.get_packages().values_list('name', flat=True))
def get_signed_in(self, obj):
return obj.is_access_granted(self.context['request']) if 'request' in self.context else None

View file

@ -6,12 +6,12 @@ from django.core.files import File
from django.http import Http404, HttpResponse
from rest_framework.decorators import detail_route
from rest_framework.response import Response
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet, ViewSet
from ...mapdata.models import FEATURE_TYPES, Level, Package, Source
from ..permissions import filter_source_queryset
from ..serializers import FeatureTypeSerializer, LevelSerializer, PackageSerializer, SourceSerializer
from .cache import AccessCachedViewSetMixin, CachedViewSetMixin
from .models import FEATURE_TYPES, Feature, Level, Package, Source
from .permissions import filter_source_queryset
from .serializers import FeatureSerializer, FeatureTypeSerializer, LevelSerializer, PackageSerializer, SourceSerializer
class LevelViewSet(CachedViewSetMixin, ReadOnlyModelViewSet):
@ -79,3 +79,15 @@ class FeatureTypeViewSet(ViewSet):
raise Http404
serializer = FeatureTypeSerializer(FEATURE_TYPES[pk], context={'request': request})
return Response(serializer.data)
ParentModelViewSet = ModelViewSet if settings.DIRECT_EDITING else ReadOnlyModelViewSet
class FeatureViewSet(ParentModelViewSet):
"""
Get all Map Features including ones that are only part of the current session
"""
queryset = Feature.objects.all()
serializer_class = FeatureSerializer
lookup_value_regex = '[^/]+'

View file

@ -4,7 +4,7 @@ from django.core.cache import cache
from django.template.response import SimpleTemplateResponse
from django.utils.cache import patch_vary_headers
from ..permissions import get_unlocked_packages
from .permissions import get_unlocked_packages
class CachedViewSetMixin:

View file

@ -1,5 +1,6 @@
from collections import OrderedDict
from django.conf import settings
from django.db import models
from django.utils.translation import ugettext_lazy as _
@ -55,6 +56,10 @@ class Package(models.Model):
def package(self):
return self
@property
def public(self):
return self.name in settings.PUBLIC_PACKAGES
@property
def bounds(self):
if self.bottom is None:

View file

@ -3,7 +3,7 @@ from django.utils.translation import ugettext_lazy as _
from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import BasePermission
from ..mapdata.models import Source
from .models import Source
def get_unlocked_packages(request):

View file

@ -0,0 +1,62 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from shapely.geometry import mapping, shape
from .models import Feature, Level, Package, Source
from .utils import sort_geojson
class GeometryField(serializers.DictField):
"""
shapely geometry objects serialized using GeoJSON
"""
default_error_messages = {
'invalid': _('Invalid GeoJSON.')
}
def to_representation(self, obj):
geojson = sort_geojson(mapping(obj))
return super().to_representation(geojson)
def to_internal_value(self, data):
geojson = super().to_internal_value(data)
try:
return shape(geojson)
except:
raise ValidationError(_('Invalid GeoJSON.'))
class LevelSerializer(serializers.ModelSerializer):
class Meta:
model = Level
fields = ('name', 'altitude', 'package')
class PackageSerializer(serializers.ModelSerializer):
class Meta:
model = Package
fields = ('name', 'home_repo', 'commit_id', 'depends', 'bounds', 'public')
readonly_fields = ('commit_id', )
class SourceSerializer(serializers.ModelSerializer):
class Meta:
model = Source
fields = ('name', 'package', 'bounds')
class FeatureTypeSerializer(serializers.Serializer):
name = serializers.CharField()
title = serializers.CharField()
title_plural = serializers.CharField()
geomtype = serializers.CharField()
color = serializers.CharField()
class FeatureSerializer(serializers.ModelSerializer):
geometry = GeometryField()
class Meta:
model = Feature
fields = ('name', 'package', 'feature_type', 'geometry')

View file

@ -47,6 +47,7 @@ else:
debug_fallback = "runserver" in sys.argv
DEBUG = config.getboolean('django', 'debug', fallback=debug_fallback)
DIRECT_EDITING = config.getboolean('c3nav', 'enable_editor', fallback=DEBUG)
PUBLIC_PACKAGES = [n for n in config.get('c3nav', 'public_packages', fallback='').split(',') if n]
EDITOR_HOSTERS = OrderedDict((name[7:], data) for name, data in config.items() if name.startswith('hoster:'))
@ -168,7 +169,7 @@ REST_FRAMEWORK = {
'ALLOWED_VERSIONS': ['v1'],
'DEFAULT_VERSION': 'v1',
'DEFAULT_PERMISSION_CLASSES': (
'c3nav.api.permissions.LockedMapFeatures',
'c3nav.mapdata.permissions.LockedMapFeatures',
),
'DEFAULT_FILTER_BACKENDS': (
'rest_framework.filters.DjangoFilterBackend',