-
Notifications
You must be signed in to change notification settings - Fork 282
/
widgets.py
99 lines (82 loc) · 4 KB
/
widgets.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import warnings
from django import forms
from django.contrib.gis.forms.widgets import BaseGeometryWidget
from django.core import validators
from django.template.defaultfilters import slugify
from django.templatetags.static import static
from leaflet import app_settings, PLUGINS, PLUGIN_FORMS
class LeafletWidget(BaseGeometryWidget):
template_name = 'leaflet/widget.html'
map_srid = 4326
modifiable = True
supports_3d = False
include_media = False
settings_overrides = {}
csp_nonce = None
@property
def media(self):
if not self.include_media:
return forms.Media()
# We assume that including media for widget means there is
# no Leaflet at all in the page.
js = [
'leaflet/leaflet.js',
'leaflet/leaflet.extras.js',
*PLUGINS[PLUGIN_FORMS]['js'],
]
css = ['leaflet/leaflet.css'] + PLUGINS[PLUGIN_FORMS]['css']
return forms.Media(js=js, css={'screen': css})
def serialize(self, value):
return value.geojson if value else ''
def _get_attrs(self, name, attrs=None):
"""Get additional attributes for template context
Some important attributes needed for rendering the map widget
are not part of the widget context but rather of the global
template context.
When using e.g. :class:`django.forms.MultiWidget`, this global
context will not be accessible. For this reason, this method
has been made public so that it can be used in custom multi
widgets.
.. deprecated:: 0.28.1
Use :meth:`.get_attrs` instead.
"""
warnings.warn(
'Method \'LeafletWidget._get_attrs\' has been deprecated. Consider calling '
'\'LeafletWidget.get_attrs\' instead.',
DeprecationWarning
)
return self.get_attrs(name, attrs=attrs)
def get_attrs(self, name, attrs=None):
assert self.map_srid == 4326, 'Leaflet vectors should be decimal degrees.'
# Retrieve params from Field init (if any)
self.geom_type = self.attrs.get('geom_type', self.geom_type)
self.settings_overrides = self.attrs.get('settings_overrides', self.settings_overrides)
# Setting 'loadevent' added in the widget constructor
loadevent = self.attrs.get('loadevent', app_settings.get('LOADEVENT'))
attrs = attrs or {}
# In BaseGeometryWidget, geom_type is set using gdal, and fails with generic.
# See https://code.djangoproject.com/ticket/21021
if self.geom_type == 'GEOMETRY':
attrs['geom_type'] = 'Geometry'
map_id_css = slugify(attrs.get('id', name)) # id need to have - for the inline formset to replace the prefix
map_id = map_id_css.replace('-', '_') # JS-safe
attrs.update(id=map_id,
id_css=map_id_css,
module='geodjango_%s' % map_id,
id_map=map_id_css + '-map',
id_map_callback=map_id + '_map_callback',
loadevent=loadevent,
modifiable=self.modifiable,
target_map=attrs.get('target_map', getattr(self, 'target_map', None)),
settings_overrides=attrs.get('settings_overrides', getattr(self, 'settings_overrides', None)),
geometry_field_class=attrs.get('geometry_field_class', getattr(self, 'geometry_field_class', 'L.GeometryField')),
field_store_class=attrs.get('field_store_class', getattr(self, 'field_store_class', 'L.FieldStore')))
return attrs
def get_context(self, name, value, attrs):
value = None if value in validators.EMPTY_VALUES else value
context = super().get_context(name, value, attrs)
context.update(self.get_attrs(name, attrs))
context["csp_nonce"] = self.csp_nonce
context["FORCE_IMAGE_PATH"] = app_settings.get('FORCE_IMAGE_PATH')
context["reset_view_icon"] = static("leaflet/images/reset-view.png")
return context