流块中的自定义字段面板性能
Custom field panel performance in stream block
我正在使用 wagtailgmaps 将 google 地图功能添加到我的项目中。用它
很简单,我想添加一个流块以供使用 Google Maps 块到
内容.
但是,我们有一个大问题,这个包只添加了一个新的edit_handler,它没有添加一个新的模型或字段,只为管理员添加一个新的处理程序。
所以,我的问题是,如何创建 Google Maps 流块添加
处理程序功能?
谢谢!
要创建一个新的StreamBlock
,您是否需要为您的字段创建一个小部件:
def render_form(self, value, prefix='', errors=None):
widget = self.field.widget
widget_attrs = {'id': prefix, 'placeholder': self.label}
field_value = self.value_for_form(value)
if hasattr(widget, 'render_with_errors'):
widget_html = widget.render_with_errors(prefix, field_value, attrs=widget_attrs, errors=errors)
widget_has_rendered_errors = True
else:
widget_html = widget.render(prefix, field_value, attrs=widget_attrs)
widget_has_rendered_errors = False
return render_to_string('wagtailadmin/block_forms/field.html', {
'name': self.name,
'classes': self.meta.classname,
'widget': widget_html,
'field': self.field,
'errors': errors if (not widget_has_rendered_errors) else None
})
一般情况下,base core中的所有block都有这个功能,使用widget就可以看到。
所以,首先我们必须为地图创建一个小部件:
class MapsField(HiddenInput):
***
def __init__(self, *args, **kwargs):
self.address_field = kwargs.pop('address_field', self.address_field)
***
super(MapField, self).__init__(*args, **kwargs)
class Media:
css = {
'all': ('*/**/geo-field.css',)
}
js = (
'*/**/geo-field.js',
'https://maps.google.com/maps/api/js?key={}&libraries=places'
.format(
GOOGLE_MAPS_V3_APIKEY
),
)
def render(self, name, value, attrs=None):
out = super(MapField, self).render(name, value, attrs)
location = format_html(
'<div class="input">'
'<input id="_id_{}_latlng" class="geo-field-location" maxlength="250" type="text">' # NOQA
'</div>',
name
)
***
return mark_safe(
'<script>window["{}"] = {};</script>'.format(data_id, json_data) +
out +
location +
'<div class="geo-field" data-data-id="{}"></div>'.format(data_id) +
"""
<script>
(function(){
if (document.readyState === 'complete') {
return initializeGeoFields();
}
$(window).load(function() {
initializeGeoFields();
});
})();
</script>
"""
)
现在,我们将创建一个扩展默认块的新块 wagtail
block:from
from wagtail.wagtailcore.blocks import FieldBlock
from wagtailgeowidget.widgets import GeoField
def __init__(self, address_field=None, required=True, help_text=None,
**kwargs):
self.field_options = {}
self.address_field = address_field
super(GeoBlock, self).__init__(**kwargs)
@cached_property
def field(self):
field_kwargs = {'widget': GeoField(
srid=4326,
id_prefix='',
address_field=self.address_field,
)}
field_kwargs.update(self.field_options)
return forms.CharField(**field_kwargs)
def clean(self, value):
if not value:
value = "SRID={};POINT({} {})".format(
4326,
GEO_WIDGET_DEFAULT_LOCATION['lng'],
GEO_WIDGET_DEFAULT_LOCATION['lat']
)
return super(GeoBlock, self).clean(value)
def render_form(self, value, prefix='', errors=None):
if value and isinstance(value, dict):
value = "SRID={};POINT({} {})".format(value['srid'],
value['lng'],
value['lat'])
return super(GeoBlock, self).render_form(value, prefix, errors)
def to_python(self, value):
if isinstance(value, dict):
return value
value = geosgeometry_str_to_struct(value)
value = {
'lat': value['y'],
'lng': value['x'],
'srid': value['srid'],
}
return super(MapBlock, self).to_python(value)
这基本上就是wagtail
块的结构。
我正在使用 wagtailgmaps 将 google 地图功能添加到我的项目中。用它 很简单,我想添加一个流块以供使用 Google Maps 块到 内容.
但是,我们有一个大问题,这个包只添加了一个新的edit_handler,它没有添加一个新的模型或字段,只为管理员添加一个新的处理程序。
所以,我的问题是,如何创建 Google Maps 流块添加 处理程序功能?
谢谢!
要创建一个新的StreamBlock
,您是否需要为您的字段创建一个小部件:
def render_form(self, value, prefix='', errors=None):
widget = self.field.widget
widget_attrs = {'id': prefix, 'placeholder': self.label}
field_value = self.value_for_form(value)
if hasattr(widget, 'render_with_errors'):
widget_html = widget.render_with_errors(prefix, field_value, attrs=widget_attrs, errors=errors)
widget_has_rendered_errors = True
else:
widget_html = widget.render(prefix, field_value, attrs=widget_attrs)
widget_has_rendered_errors = False
return render_to_string('wagtailadmin/block_forms/field.html', {
'name': self.name,
'classes': self.meta.classname,
'widget': widget_html,
'field': self.field,
'errors': errors if (not widget_has_rendered_errors) else None
})
一般情况下,base core中的所有block都有这个功能,使用widget就可以看到。
所以,首先我们必须为地图创建一个小部件:
class MapsField(HiddenInput):
***
def __init__(self, *args, **kwargs):
self.address_field = kwargs.pop('address_field', self.address_field)
***
super(MapField, self).__init__(*args, **kwargs)
class Media:
css = {
'all': ('*/**/geo-field.css',)
}
js = (
'*/**/geo-field.js',
'https://maps.google.com/maps/api/js?key={}&libraries=places'
.format(
GOOGLE_MAPS_V3_APIKEY
),
)
def render(self, name, value, attrs=None):
out = super(MapField, self).render(name, value, attrs)
location = format_html(
'<div class="input">'
'<input id="_id_{}_latlng" class="geo-field-location" maxlength="250" type="text">' # NOQA
'</div>',
name
)
***
return mark_safe(
'<script>window["{}"] = {};</script>'.format(data_id, json_data) +
out +
location +
'<div class="geo-field" data-data-id="{}"></div>'.format(data_id) +
"""
<script>
(function(){
if (document.readyState === 'complete') {
return initializeGeoFields();
}
$(window).load(function() {
initializeGeoFields();
});
})();
</script>
"""
)
现在,我们将创建一个扩展默认块的新块 wagtail
block:from
from wagtail.wagtailcore.blocks import FieldBlock
from wagtailgeowidget.widgets import GeoField
def __init__(self, address_field=None, required=True, help_text=None,
**kwargs):
self.field_options = {}
self.address_field = address_field
super(GeoBlock, self).__init__(**kwargs)
@cached_property
def field(self):
field_kwargs = {'widget': GeoField(
srid=4326,
id_prefix='',
address_field=self.address_field,
)}
field_kwargs.update(self.field_options)
return forms.CharField(**field_kwargs)
def clean(self, value):
if not value:
value = "SRID={};POINT({} {})".format(
4326,
GEO_WIDGET_DEFAULT_LOCATION['lng'],
GEO_WIDGET_DEFAULT_LOCATION['lat']
)
return super(GeoBlock, self).clean(value)
def render_form(self, value, prefix='', errors=None):
if value and isinstance(value, dict):
value = "SRID={};POINT({} {})".format(value['srid'],
value['lng'],
value['lat'])
return super(GeoBlock, self).render_form(value, prefix, errors)
def to_python(self, value):
if isinstance(value, dict):
return value
value = geosgeometry_str_to_struct(value)
value = {
'lat': value['y'],
'lng': value['x'],
'srid': value['srid'],
}
return super(MapBlock, self).to_python(value)
这基本上就是wagtail
块的结构。