remove name field from most mapdata models
This commit is contained in:
parent
baecf08aea
commit
89ab60b395
10 changed files with 96 additions and 39 deletions
|
@ -9,5 +9,5 @@ urlpatterns = [
|
|||
url(r'^mapitems/(?P<mapitem_type>[^/]+)/list/$', list_mapitems, name='editor.mapitems'),
|
||||
url(r'^mapitems/(?P<mapitem_type>[^/]+)/list/(?P<level>[^/]+)/$', list_mapitems, name='editor.mapitems.level'),
|
||||
url(r'^mapitems/(?P<mapitem_type>[^/]+)/add/$', edit_mapitem, name='editor.mapitems.add'),
|
||||
url(r'^mapitems/(?P<mapitem_type>[^/]+)/edit/(?P<name>[^/]+)/$', edit_mapitem, name='editor.mapitems.edit'),
|
||||
url(r'^mapitems/(?P<mapitem_type>[^/]+)/edit/(?P<id>[^/]+)/$', edit_mapitem, name='editor.mapitems.edit'),
|
||||
]
|
||||
|
|
|
@ -4,11 +4,12 @@ from django.http.response import Http404
|
|||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
|
||||
from c3nav.access.apply import can_access, filter_queryset_by_access
|
||||
from c3nav.mapdata.models import AreaLocation
|
||||
from c3nav.mapdata.models import AreaLocation, Level
|
||||
from c3nav.mapdata.models.base import FEATURE_TYPES
|
||||
|
||||
|
||||
def list_mapitemtypes(request, level):
|
||||
level = get_object_or_404()
|
||||
def get_item_count(mapitemtype):
|
||||
if hasattr(mapitemtype, 'level'):
|
||||
return filter_queryset_by_access(request, mapitemtype.objects.filter(level__name=level)).count()
|
||||
|
@ -43,11 +44,13 @@ def list_mapitems(request, mapitem_type, level=None):
|
|||
return redirect('editor.mapitems', mapitem_type=mapitem_type)
|
||||
|
||||
queryset = mapitemtype.objects.all().order_by('name')
|
||||
|
||||
if level is not None:
|
||||
level = get_object_or_404(Level, level)
|
||||
if hasattr(mapitemtype, 'level'):
|
||||
queryset = queryset.filter(level__name=level)
|
||||
queryset = queryset.filter(level=level)
|
||||
elif hasattr(mapitemtype, 'levels'):
|
||||
queryset = queryset.filter(levels__name=level)
|
||||
queryset = queryset.filter(levels=level)
|
||||
|
||||
queryset = filter_queryset_by_access(request, queryset)
|
||||
|
||||
|
@ -62,7 +65,7 @@ def list_mapitems(request, mapitem_type, level=None):
|
|||
'has_levels': hasattr(mapitemtype, 'levels'),
|
||||
'has_altitude': hasattr(mapitemtype, 'altitude'),
|
||||
'has_intermediate': hasattr(mapitemtype, 'intermediate'),
|
||||
'level': level,
|
||||
'level': level.id,
|
||||
'items': queryset,
|
||||
})
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import mimetypes
|
|||
import hashlib
|
||||
from collections import OrderedDict
|
||||
from django.http import Http404, HttpResponse, HttpResponseNotModified
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework.decorators import detail_route, list_route
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
|
||||
|
@ -48,10 +49,7 @@ class GeometryViewSet(ViewSet):
|
|||
|
||||
level = None
|
||||
if 'level' in request.GET:
|
||||
levels_cached = get_levels_cached()
|
||||
level_name = request.GET['level']
|
||||
if level_name in levels_cached:
|
||||
level = levels_cached[level_name]
|
||||
level = get_object_or_404(Level, id=request.GET['level'])
|
||||
|
||||
cache_key = '__'.join((
|
||||
','.join([str(i) for i in types]),
|
||||
|
@ -78,7 +76,7 @@ class GeometryViewSet(ViewSet):
|
|||
else:
|
||||
queryset = queryset.none()
|
||||
queryset = filter_queryset_by_access(request, queryset)
|
||||
queryset = queryset.order_by('name')
|
||||
queryset = queryset.order_by('id')
|
||||
|
||||
for field_name in ('level', 'crop_to_level', 'elevator'):
|
||||
if hasattr(mapitemtype, field_name):
|
||||
|
@ -105,9 +103,7 @@ class LevelViewSet(CachedReadOnlyViewSetMixin, ReadOnlyModelViewSet):
|
|||
"""
|
||||
queryset = Level.objects.all()
|
||||
serializer_class = LevelSerializer
|
||||
lookup_field = 'name'
|
||||
lookup_value_regex = '[^/]+'
|
||||
ordering = ('altitude',)
|
||||
lookup_field = 'id'
|
||||
|
||||
|
||||
class SourceViewSet(CachedReadOnlyViewSetMixin, ReadOnlyModelViewSet):
|
||||
|
@ -116,9 +112,7 @@ class SourceViewSet(CachedReadOnlyViewSetMixin, ReadOnlyModelViewSet):
|
|||
"""
|
||||
queryset = Source.objects.all()
|
||||
serializer_class = SourceSerializer
|
||||
lookup_field = 'name'
|
||||
lookup_value_regex = '[^/]+'
|
||||
ordering = ('name',)
|
||||
lookup_field = 'id'
|
||||
|
||||
def get_queryset(self):
|
||||
return filter_queryset_by_access(self.request, super().get_queryset().all())
|
||||
|
@ -140,11 +134,11 @@ class LocationViewSet(ViewSet):
|
|||
List and retrieve locations
|
||||
"""
|
||||
# We don't cache this, because it depends on access_list
|
||||
lookup_field = 'name'
|
||||
lookup_field = 'location_id'
|
||||
|
||||
@staticmethod
|
||||
def _filter(queryset):
|
||||
return queryset.filter(can_search=True).order_by('name')
|
||||
return queryset.filter(can_search=True).order_by('id')
|
||||
|
||||
def list(self, request, **kwargs):
|
||||
etag = hashlib.sha256(json.dumps({
|
||||
|
@ -168,8 +162,8 @@ class LocationViewSet(ViewSet):
|
|||
response['Cache-Control'] = 'no-cache'
|
||||
return response
|
||||
|
||||
def retrieve(self, request, name=None, **kwargs):
|
||||
location = get_location(request, name)
|
||||
def retrieve(self, request, location_id=None, **kwargs):
|
||||
location = get_location(request, location_id)
|
||||
if location is None:
|
||||
raise Http404
|
||||
return Response(location.to_location_json())
|
||||
|
|
57
src/c3nav/mapdata/migrations/0055_auto_20170505_1334.py
Normal file
57
src/c3nav/mapdata/migrations/0055_auto_20170505_1334.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.4 on 2017-05-05 13:34
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mapdata', '0054_remove_obstacle_crop_to_level'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='arealocation',
|
||||
old_name='name',
|
||||
new_name='slug',
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='locationgroup',
|
||||
old_name='name',
|
||||
new_name='slug',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='area',
|
||||
name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='building',
|
||||
name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='door',
|
||||
name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='hole',
|
||||
name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='lineobstacle',
|
||||
name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='obstacle',
|
||||
name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='stair',
|
||||
name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='stuffedarea',
|
||||
name='name',
|
||||
),
|
||||
]
|
|
@ -32,8 +32,6 @@ class FeatureBase(ModelBase):
|
|||
|
||||
|
||||
class Feature(models.Model, metaclass=FeatureBase):
|
||||
name = models.SlugField(_('Name'), unique=True, max_length=50)
|
||||
|
||||
EditorForm = None
|
||||
|
||||
@property
|
||||
|
@ -71,7 +69,7 @@ class GeometryFeature(Feature):
|
|||
def get_geojson_properties(self):
|
||||
return OrderedDict((
|
||||
('type', self.__class__.__name__.lower()),
|
||||
('name', self.name),
|
||||
('id', self.id),
|
||||
))
|
||||
|
||||
def to_geojson(self):
|
||||
|
|
|
@ -19,7 +19,7 @@ class LevelFeature(GeometryFeature):
|
|||
|
||||
def get_geojson_properties(self):
|
||||
result = super().get_geojson_properties()
|
||||
result['level'] = self.level.name
|
||||
result['level'] = self.level.id
|
||||
return result
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ class AreaFeature(GeometryFeature):
|
|||
|
||||
def get_geojson_properties(self):
|
||||
result = super().get_geojson_properties()
|
||||
result['area'] = self.area.name
|
||||
result['area'] = self.area.id
|
||||
return result
|
||||
|
||||
|
||||
|
@ -124,8 +124,8 @@ class Stair(AreaFeature):
|
|||
('properties', OrderedDict((
|
||||
('type', 'shadow'),
|
||||
('original_type', self.__class__.__name__.lower()),
|
||||
('original_name', self.name),
|
||||
('area', self.area.name),
|
||||
('original_id', self.id),
|
||||
('area', self.area.id),
|
||||
))),
|
||||
('geometry', format_geojson(mapping(shadow), round=False)),
|
||||
))
|
||||
|
|
|
@ -25,7 +25,8 @@ class Location:
|
|||
|
||||
def to_location_json(self):
|
||||
return OrderedDict((
|
||||
('id', self.location_id),
|
||||
('id', self.id),
|
||||
('location_id', self.location_id),
|
||||
('title', str(self.title)),
|
||||
('subtitle', str(self.subtitle)),
|
||||
))
|
||||
|
@ -35,6 +36,7 @@ class Location:
|
|||
class LocationModelMixin(Location):
|
||||
def get_geojson_properties(self):
|
||||
result = super().get_geojson_properties()
|
||||
result['slug'] = self.slug
|
||||
result['titles'] = OrderedDict(sorted(self.titles.items()))
|
||||
return result
|
||||
|
||||
|
@ -44,6 +46,7 @@ class LocationModelMixin(Location):
|
|||
|
||||
|
||||
class LocationGroup(LocationModelMixin, Feature):
|
||||
slug = models.SlugField(_('Name'), unique=True, max_length=50)
|
||||
titles = JSONField()
|
||||
can_search = models.BooleanField(default=True, verbose_name=_('can be searched'))
|
||||
can_describe = models.BooleanField(default=True, verbose_name=_('can be used to describe a position'))
|
||||
|
@ -58,14 +61,14 @@ class LocationGroup(LocationModelMixin, Feature):
|
|||
|
||||
@cached_property
|
||||
def location_id(self):
|
||||
return 'g:'+self.name
|
||||
return 'g:'+self.slug
|
||||
|
||||
def get_in_levels(self):
|
||||
last_update = get_last_mapdata_update()
|
||||
if last_update is None:
|
||||
return self._get_in_levels()
|
||||
|
||||
cache_key = 'c3nav__mapdata__locationgroup__in_levels__'+last_update.isoformat()+'__'+self.name,
|
||||
cache_key = 'c3nav__mapdata__locationgroup__in_levels__'+last_update.isoformat()+'__'+str(self.id),
|
||||
in_levels = cache.get(cache_key)
|
||||
if not in_levels:
|
||||
in_levels = self._get_in_levels()
|
||||
|
@ -115,6 +118,7 @@ class AreaLocation(LocationModelMixin, LevelFeature):
|
|||
('needs_permission', _('Excluded, needs permission to include')),
|
||||
)
|
||||
|
||||
slug = models.SlugField(_('Name'), unique=True, max_length=50)
|
||||
location_type = models.CharField(max_length=20, choices=LOCATION_TYPES, verbose_name=_('Location Type'))
|
||||
titles = JSONField()
|
||||
groups = models.ManyToManyField(LocationGroup, verbose_name=_('Location Groups'), blank=True)
|
||||
|
@ -137,14 +141,14 @@ class AreaLocation(LocationModelMixin, LevelFeature):
|
|||
|
||||
@cached_property
|
||||
def location_id(self):
|
||||
return self.name
|
||||
return self.slug
|
||||
|
||||
def get_in_areas(self):
|
||||
last_update = get_last_mapdata_update()
|
||||
if last_update is None:
|
||||
return self._get_in_areas()
|
||||
|
||||
cache_key = 'c3nav__mapdata__location__in_areas__'+last_update.isoformat()+'__'+self.name,
|
||||
cache_key = 'c3nav__mapdata__location__in_areas__'+last_update.isoformat()+'__'+str(self.id),
|
||||
in_areas = cache.get(cache_key)
|
||||
if not in_areas:
|
||||
in_areas = self._get_in_areas()
|
||||
|
|
|
@ -8,6 +8,7 @@ class Source(Feature):
|
|||
"""
|
||||
A map source, images of levels that can be useful as backgrounds for the map editor
|
||||
"""
|
||||
name = models.SlugField(_('Name'), unique=True, max_length=50)
|
||||
bottom = models.DecimalField(_('bottom coordinate'), max_digits=6, decimal_places=2)
|
||||
left = models.DecimalField(_('left coordinate'), max_digits=6, decimal_places=2)
|
||||
top = models.DecimalField(_('top coordinate'), max_digits=6, decimal_places=2)
|
||||
|
|
|
@ -8,8 +8,8 @@ from c3nav.mapdata.models.locations import PointLocation
|
|||
from c3nav.mapdata.utils.cache import get_levels_cached
|
||||
|
||||
|
||||
def get_location(request, name):
|
||||
match = re.match('^c:(?P<level>[a-z0-9-_]+):(?P<x>[0-9]+):(?P<y>[0-9]+)$', name)
|
||||
def get_location(request, location_id):
|
||||
match = re.match('^c:(?P<level>[a-z0-9-_]+):(?P<x>[0-9]+):(?P<y>[0-9]+)$', location_id)
|
||||
if match:
|
||||
levels = get_levels_cached()
|
||||
level = levels.get(match.group('level'))
|
||||
|
@ -17,11 +17,11 @@ def get_location(request, name):
|
|||
return None
|
||||
return PointLocation(level=level, x=int(match.group('x'))/100, y=int(match.group('y'))/100, request=request)
|
||||
|
||||
if name.startswith('g:'):
|
||||
queryset = LocationGroup.objects.filter(Q(name=name[2:], can_search=True))
|
||||
if location_id.startswith('g:'):
|
||||
queryset = LocationGroup.objects.filter(Q(slug=location_id[2:], can_search=True))
|
||||
return filter_queryset_by_access(request, queryset).first()
|
||||
|
||||
return filter_arealocations_by_access(request, AreaLocation.objects.filter(name=name, can_search=True)).first()
|
||||
return filter_arealocations_by_access(request, AreaLocation.objects.filter(slug=location_id, can_search=True)).first()
|
||||
|
||||
|
||||
def filter_words(queryset, words):
|
||||
|
|
|
@ -6,10 +6,10 @@ from c3nav.mapdata.models import Level, Source
|
|||
class LevelSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Level
|
||||
fields = ('name', 'altitude')
|
||||
fields = ('id', 'name', 'altitude')
|
||||
|
||||
|
||||
class SourceSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Source
|
||||
fields = ('name', 'bounds')
|
||||
fields = ('id', 'name', 'bounds')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue