class ImageFormMixin(EntangledModelFormMixin): image_file = AdminImageFormField( ManyToOneRel(FilerImageField, Image, 'file_ptr'), Image.objects.all(), to_field_name='image_file', label=_("Image"), ) image_title = CharField( label=_('Image Title'), required=False, help_text=_("Caption text added to the 'title' attribute of the <img> element."), ) alt_tag = CharField( label=_('Alternative Description'), required=False, help_text=_("Textual description of the image added to the 'alt' tag of the <img> element."), ) _image_properties = EntangledField() class Meta: entangled_fields = {'glossary': ['image_file', 'image_title', 'alt_tag', '_image_properties']} def clean(self): cleaned_data = super().clean() image_file = cleaned_data.get('image_file') if not image_file: raise ValidationError(_("No image has been selected.")) # _image_properties are just a cached representation, maybe useless cleaned_data['_image_properties'] = { 'width': image_file._width, 'height': image_file._height, 'exif_orientation': image_file.exif.get('Orientation', 1), } return cleaned_data
class MarkerForm(EntangledModelForm): title = CharField( label=_("Marker Title"), widget=widgets.TextInput(attrs={'size': 60}), help_text=_( "Please choose a title, then go to the map to set a marker pin")) use_icon = BooleanField( label=_("Use customized marker icon"), initial=False, required=False, ) marker_image = AdminImageFormField( ManyToOneRel(FilerImageField, Image, 'file_ptr'), Image.objects.all(), label=_("Marker Image"), required=False, to_field_name='image_file', ) marker_width = SizeField( label=_("Marker Width"), allowed_units=['px'], required=False, help_text=_("Width of the marker icon in pixels."), ) marker_anchor = MultiSizeField( ['left', 'top'], label=_("Marker Anchor"), allowed_units=['px', '%'], required=False, help_text= _("The coordinates of the icon's anchor (relative to its top left corner)." ), ) popup_text = HTMLFormField( required=False, help_text=_("Optional rich text to display in popup."), ) position = HiddenDictField() class Meta: entangled_fields = { 'glossary': [ 'title', 'use_icon', 'marker_image', 'marker_width', 'marker_anchor', 'popup_text', 'position' ] } def clean(self): cleaned_data = super().clean() try: position = cleaned_data['position'] if isinstance(position, str): position = json.loads(position) elif not isinstance(position, dict): raise ValueError except (ValueError, KeyError): raise ValidationError( "Invalid internal position data. Check your Javascript imports." ) else: if 'lat' not in position or 'lng' not in position: # place the marker in the center of the current map position = { k: v for k, v in self.instance.cascade_element. glossary['map_position'].items() if k in ['lat', 'lng'] } cleaned_data['position'] = position popup_text = cleaned_data.pop('popup_text', '') if strip_tags(popup_text): cleaned_data['popup_text'] = strip_spaces_between_tags(popup_text) return cleaned_data