import json from collections import OrderedDict from django.conf import settings from django.forms import CharField, ModelForm, ValidationError from django.forms.widgets import HiddenInput from django.utils.translation import ugettext_lazy as _ from shapely.geometry.geo import mapping class MapitemFormMixin(ModelForm): def __init__(self, *args, request=None, **kwargs): self.request = request super().__init__(*args, **kwargs) creating = not self.instance.pk if 'section' in self.fields: # hide section widget self.fields['section'].widget = HiddenInput() if 'space' in self.fields: # hide space widget self.fields['space'].widget = HiddenInput() if 'geometry' in self.fields: # hide geometry widget self.fields['geometry'].widget = HiddenInput() if not creating: self.initial['geometry'] = json.dumps(mapping(self.instance.geometry), separators=(',', ':')) if 'groups' in self.fields: self.fields['groups'].label_from_instance = lambda obj: obj.title_for_forms # parse titles self.titles = None if hasattr(self.instance, 'titles'): titles = OrderedDict((lang_code, '') for lang_code, language in settings.LANGUAGES) if self.instance is not None and self.instance.pk: titles.update(self.instance.titles) language_titles = dict(settings.LANGUAGES) for language in reversed(titles.keys()): new_title = self.data.get('title_' + language) if new_title is not None: titles[language] = new_title self.fields['title_' + language] = CharField(label=language_titles.get(language, language), required=False, initial=titles[language].strip(), max_length=50) self.fields.move_to_end('title_' + language, last=False) self.titles = titles def clean(self): if 'geometry' in self.fields: if not self.cleaned_data.get('geometry'): raise ValidationError('Missing geometry.') if hasattr(self.instance, 'titles') and not any(self.titles.values()): raise ValidationError( _('You have to select a title in at least one language.') ) super().clean() def create_editor_form(editor_model): possible_fields = ['name', 'altitude', 'level', 'category', 'width', 'groups', 'color', 'public', 'can_search', 'can_describe', 'outside', 'stuffed', 'geometry', 'left', 'top', 'right', 'bottom'] field_names = [field.name for field in editor_model._meta.get_fields()] existing_fields = [name for name in possible_fields if name in field_names] class EditorForm(MapitemFormMixin, ModelForm): class Meta: model = editor_model fields = existing_fields editor_model.EditorForm = EditorForm def create_editor_forms(): from c3nav.mapdata.models.base import EDITOR_FORM_MODELS for mapitemtype in EDITOR_FORM_MODELS.values(): create_editor_form(mapitemtype)