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 json
|
||||||
import operator
|
import operator
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
|
from django.core.cache import cache
|
||||||
from django.core.exceptions import FieldDoesNotExist
|
from django.core.exceptions import FieldDoesNotExist
|
||||||
|
from django.db.models import Q
|
||||||
from django.forms import (BooleanField, CharField, ChoiceField, Form, ModelChoiceField, ModelForm, MultipleChoiceField,
|
from django.forms import (BooleanField, CharField, ChoiceField, Form, ModelChoiceField, ModelForm, MultipleChoiceField,
|
||||||
ValidationError)
|
ValidationError)
|
||||||
from django.forms.widgets import HiddenInput
|
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.fields import GeometryField
|
||||||
from c3nav.mapdata.forms import I18nModelFormMixin
|
from c3nav.mapdata.forms import I18nModelFormMixin
|
||||||
from c3nav.mapdata.models import GraphEdge
|
from c3nav.mapdata.models import GraphEdge
|
||||||
|
from c3nav.mapdata.models.access import AccessPermission
|
||||||
|
|
||||||
|
|
||||||
class EditorFormBase(I18nModelFormMixin, ModelForm):
|
class EditorFormBase(I18nModelFormMixin, ModelForm):
|
||||||
def __init__(self, *args, request=None, **kwargs):
|
def __init__(self, *args, space_id=None, request=None, **kwargs):
|
||||||
self.request = request
|
self.request = request
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
creating = not self.instance.pk
|
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'].label_from_instance = lambda obj: obj.title
|
||||||
self.fields['access_restriction'].queryset = AccessRestriction.qs_for_request(self.request)
|
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 = 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'):
|
for space_field in ('origin_space', 'target_space'):
|
||||||
if space_field in self.fields:
|
if space_field in self.fields:
|
||||||
self.fields[space_field].label_from_instance = lambda obj: obj.title
|
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,
|
'geomtype': model._meta.get_field('geometry').geomtype,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
space_id = None
|
||||||
if model == Level:
|
if model == Level:
|
||||||
ctx.update({
|
ctx.update({
|
||||||
'level': obj,
|
'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),
|
'geometry_url': '/api/editor/geometries/?level='+str(level.primary_level_pk),
|
||||||
})
|
})
|
||||||
elif hasattr(model, 'space'):
|
elif hasattr(model, 'space'):
|
||||||
|
space_id = space.pk
|
||||||
if not new:
|
if not new:
|
||||||
space = obj.space
|
space = obj.space
|
||||||
ctx.update({
|
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
|
ctx['obj_title'] = obj.title
|
||||||
return render(request, 'editor/delete.html', ctx)
|
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():
|
if form.is_valid():
|
||||||
# Update/create objects
|
# Update/create objects
|
||||||
obj = form.save(commit=False)
|
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.'))
|
messages.error(request, _('You can not edit changes on this changeset.'))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
form = model.EditorForm(instance=obj, request=request)
|
form = model.EditorForm(instance=obj, request=request, space_id=space_id)
|
||||||
|
|
||||||
ctx.update({
|
ctx.update({
|
||||||
'form': form,
|
'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')
|
sub_qs = Space.objects.filter(Space.q_for_request(request)).select_related('level').defer('geometry')
|
||||||
space = get_object_or_404(sub_qs, pk=space)
|
space = get_object_or_404(sub_qs, pk=space)
|
||||||
queryset = queryset.filter(space=space)
|
queryset = queryset.filter(space=space)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
model._meta.get_field('geometry')
|
model._meta.get_field('geometry')
|
||||||
except FieldDoesNotExist:
|
except FieldDoesNotExist:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
queryset = queryset.defer('geometry')
|
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({
|
ctx.update({
|
||||||
'levels': Level.objects.filter(Level.q_for_request(request), on_top_of__isnull=True),
|
'levels': Level.objects.filter(Level.q_for_request(request), on_top_of__isnull=True),
|
||||||
'level': space.level,
|
'level': space.level,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue