edit route descriptions: only suggest neighbor spaces
This commit is contained in:
parent
0a0bf9972a
commit
b32b5c2beb
2 changed files with 55 additions and 5 deletions
|
@ -1,8 +1,11 @@
|
|||
import json
|
||||
import operator
|
||||
from functools import reduce
|
||||
from itertools import chain
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.core.exceptions import FieldDoesNotExist
|
||||
from django.db.models import Q
|
||||
from django.forms import (BooleanField, CharField, ChoiceField, Form, ModelChoiceField, ModelForm, MultipleChoiceField,
|
||||
ValidationError)
|
||||
from django.forms.widgets import HiddenInput
|
||||
|
@ -13,10 +16,11 @@ from c3nav.editor.models import ChangeSet, ChangeSetUpdate
|
|||
from c3nav.mapdata.fields import GeometryField
|
||||
from c3nav.mapdata.forms import I18nModelFormMixin
|
||||
from c3nav.mapdata.models import GraphEdge
|
||||
from c3nav.mapdata.models.access import AccessPermission
|
||||
|
||||
|
||||
class EditorFormBase(I18nModelFormMixin, ModelForm):
|
||||
def __init__(self, *args, request=None, **kwargs):
|
||||
def __init__(self, *args, space_id=None, request=None, **kwargs):
|
||||
self.request = request
|
||||
super().__init__(*args, **kwargs)
|
||||
creating = not self.instance.pk
|
||||
|
@ -71,9 +75,36 @@ class EditorFormBase(I18nModelFormMixin, ModelForm):
|
|||
self.fields['access_restriction'].label_from_instance = lambda obj: obj.title
|
||||
self.fields['access_restriction'].queryset = AccessRestriction.qs_for_request(self.request)
|
||||
|
||||
if 'target_space' in self.fields:
|
||||
if space_id and 'target_space' in self.fields:
|
||||
Space = self.request.changeset.wrap_model('Space')
|
||||
space_qs = Space.qs_for_request(self.request)
|
||||
|
||||
GraphNode = self.request.changeset.wrap_model('GraphNode')
|
||||
GraphEdge = self.request.changeset.wrap_model('GraphEdge')
|
||||
|
||||
cache_key = 'editor:neighbor_spaces:%s:%s%d' % (
|
||||
self.request.changeset.raw_cache_key_by_changes,
|
||||
AccessPermission.cache_key_for_request(request, with_update=False),
|
||||
space_id
|
||||
)
|
||||
other_spaces = cache.get(cache_key, None)
|
||||
if other_spaces is None:
|
||||
AccessPermission.cache_key_for_request(request, with_update=False) + ':' + str(request.user.pk or 0)
|
||||
space_nodes = set(GraphNode.objects.filter(space_id=space_id).values_list('pk', flat=True))
|
||||
space_edges = GraphEdge.objects.filter(
|
||||
Q(from_node_id__in=space_nodes) | Q(to_node_id__in=space_nodes)
|
||||
).values_list('from_node_id', 'to_node_id')
|
||||
other_nodes = set(chain(*space_edges)) - space_nodes
|
||||
other_spaces = set(GraphNode.objects.filter(pk__in=other_nodes).values_list('space_id', flat=True))
|
||||
other_spaces.discard(space_id)
|
||||
cache.set(cache_key, other_spaces, 900)
|
||||
|
||||
for space_field in ('origin_space', 'target_space'):
|
||||
other_space_id = getattr(self.instance, space_field+'_id', None)
|
||||
if other_space_id:
|
||||
other_spaces.add(other_space_id)
|
||||
|
||||
space_qs = Space.qs_for_request(self.request).filter(pk__in=other_spaces)
|
||||
|
||||
for space_field in ('origin_space', 'target_space'):
|
||||
if space_field in self.fields:
|
||||
self.fields[space_field].label_from_instance = lambda obj: obj.title
|
||||
|
|
|
@ -142,6 +142,7 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e
|
|||
'geomtype': model._meta.get_field('geometry').geomtype,
|
||||
})
|
||||
|
||||
space_id = None
|
||||
if model == Level:
|
||||
ctx.update({
|
||||
'level': obj,
|
||||
|
@ -183,6 +184,7 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e
|
|||
'geometry_url': '/api/editor/geometries/?level='+str(level.primary_level_pk),
|
||||
})
|
||||
elif hasattr(model, 'space'):
|
||||
space_id = space.pk
|
||||
if not new:
|
||||
space = obj.space
|
||||
ctx.update({
|
||||
|
@ -234,7 +236,8 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e
|
|||
ctx['obj_title'] = obj.title
|
||||
return render(request, 'editor/delete.html', ctx)
|
||||
|
||||
form = model.EditorForm(instance=model() if new else obj, data=request.POST, request=request)
|
||||
form = model.EditorForm(instance=model() if new else obj, data=request.POST,
|
||||
request=request, space_id=space_id)
|
||||
if form.is_valid():
|
||||
# Update/create objects
|
||||
obj = form.save(commit=False)
|
||||
|
@ -266,7 +269,7 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e
|
|||
messages.error(request, _('You can not edit changes on this changeset.'))
|
||||
|
||||
else:
|
||||
form = model.EditorForm(instance=obj, request=request)
|
||||
form = model.EditorForm(instance=obj, request=request, space_id=space_id)
|
||||
|
||||
ctx.update({
|
||||
'form': form,
|
||||
|
@ -319,12 +322,28 @@ def list_objects(request, model=None, level=None, space=None, explicit_edit=Fals
|
|||
sub_qs = Space.objects.filter(Space.q_for_request(request)).select_related('level').defer('geometry')
|
||||
space = get_object_or_404(sub_qs, pk=space)
|
||||
queryset = queryset.filter(space=space)
|
||||
|
||||
try:
|
||||
model._meta.get_field('geometry')
|
||||
except FieldDoesNotExist:
|
||||
pass
|
||||
else:
|
||||
queryset = queryset.defer('geometry')
|
||||
|
||||
try:
|
||||
model._meta.get_field('origin_space')
|
||||
except FieldDoesNotExist:
|
||||
pass
|
||||
else:
|
||||
queryset = queryset.select_related('origin_space')
|
||||
|
||||
try:
|
||||
model._meta.get_field('target_space')
|
||||
except FieldDoesNotExist:
|
||||
pass
|
||||
else:
|
||||
queryset = queryset.select_related('target_space')
|
||||
|
||||
ctx.update({
|
||||
'levels': Level.objects.filter(Level.q_for_request(request), on_top_of__isnull=True),
|
||||
'level': space.level,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue