Django Widgets

Geodjango后台地图默认显示原始地图,现需求为另显示高德地图(围栏编辑)

  1. 只是显示围栏,不需求编辑
    使用django的widget功能。

Widgets should not be confused with the form fields. Form fields deal with the logic of input validation and are used directly in templates. Widgets deal with rendering of HTML form input elements on the web page and extraction of raw submitted data. However, widgets do need to be assigned to form fields.

widget不同于form,widget处理HTML表单输入元素在web页面上的呈现,并提取原始提交的数据。但是,需要将widget分配到表单字段。

from django import forms
from django import template
class MultiPolygonAmapWidget(forms.TextInput):
    def render(self, name, value, attrs=None):
        if value is not None and type(value) == dict:
            lng = value.get("lng", None)
            lat = value.get("lat", None)
            multipolygon = value.get("multipolygon", None)
            radius = value.get("radius", None)
        else:
            return "地理数据未录入完全,请检查"

        if multipolygon or radius:
            t = template.Template("""
                <style type="text/css">
                .map_lo{
                    width: 600px;
                    height: 400px;
                }
                #show_location{
                    position: relative;
                    top: -16px;
                    left: 485px
                }
                #id_location{
                    display: None
                }
                </style>
                <div id="mapDivLocation" class="map_lo"></div>
                <div id="show_location"></div>
                <textarea id="id_location" class="vTextField" cols="150" rows="10" name="location" >
                    {{ lng }}, {{ lat }}
                </textarea>
                <script type="text/javascript">
                    var map_lo = new AMap.Map("mapDivLocation", {
                        resizeEnable: true,
                        center: [{{ lng }}, {{ lat }}],//地图中心点
                        zoom: 16 //地图显示的缩放级别
                    });
                    var circle = new AMap.Circle({
                        center: [{{ lng }}, {{ lat }}],// 圆心位置
                        radius: {{ radius }}, //半径
                        strokeColor: "#F33", //线颜色
                        strokeOpacity: 1, //线透明度
                        strokeWeight: 3, //线粗细度
                        fillColor: "#ee2200", //填充颜色
                        fillOpacity: 0.35//填充透明度
                    });
                    circle.setMap(map_lo);
                    var polygon = new AMap.Polygon({
                        map: map_lo,
                        path: {{ multipolygon }},
                        strokeColor: "#0000ff",
                        strokeOpacity: 1,
                        strokeWeight: 3,
                        fillColor: "#f5deb3",
                        fillOpacity: 0.35
                    });
                    polygon.setMap(map_lo);
                    map_lo.setFitView();
                </script>
                """)
            c = template.Context({
                'lng': lng,
                'lat': lat,
                'multipolygon': multipolygon,
                'radius': radius,
            })
            return t.render(c)
        else:
            return "地理数据未录入完全,请检查"
    @property
    def media(self):
        css = {
            "all": [
                # "/static/admin/js/admin/amap.css",
            ]
        }

        js = [
            "http://webapi.amap.com/maps?v=1.3&key=xxxxx&plugin=AMap.ToolBar",
        ]

        return forms.Media(js=js, css=css)

-> admin

class CustomBusinessCircleModelForm(forms.ModelForm):
    location = forms.CharField(widget=MultiPolygonAmapWidget, required=False, label="高德地图经纬度")

    def __init__(self, *args, **kwargs):
        super(CustomBusinessCircleModelForm, self).__init__(*args, **kwargs)
        self.fields['province'].queryset = Areas.objects.filter(LevelType=1)
        self.fields['city'].queryset = Areas.objects.filter(LevelType=2)
        self.fields['district'].queryset = Areas.objects.filter(LevelType=3)

        instance = kwargs.get('instance')

        if instance:
            if instance.radius:
                radius = instance.radius * 1000
            else:
                radius = 0
            if instance.boundary:
                # 第一个boundary是model定义的字段,第二个是multipolygon的属性
                multipolygon_txt = instance.boundary.boundary.coords
                multipolygon = [
                    [list(wgs84togcj02(*list(loc))) for loc in list(polygon)] for polygon in list(multipolygon_txt)
                ]
            else:
                multipolygon = []
            if instance.tencent_lng:
                location_lng = instance.tencent_lng
                location_lat = instance.tencent_lat
            elif instance.center_point:
                location_lng, location_lat = wgs84togcj02(instance.center_point.x, instance.center_point.y)
            else:
                location_lng, location_lat = 121.45575, 31.249571
            location_init_dict = {
                "lng": location_lng,
                "lat": location_lat,
                "radius": radius,
                "multipolygon": multipolygon,
            }
            self.base_fields['location'].initial = location_init_dict

        forms.ModelForm.__init__(self, *args, **kwargs)

    class Meta:
        model = BusinessCircle
        fields = '__all__'

class BusinessCircleAdmin(AdminChangelistMixin, admin.OSMGeoAdmin):
    form = CustomBusinessCircleModelForm
    list_display = ('',)
    search_fields = ('',)
    list_filter = (AreasDropdownFilter, 'business_circle_type',)
    fieldsets = (
        ('基本信息', {
            'fields': (
                'business_circle_name',
                ...
            )
        }),
        ('其他信息', {
            'classes': ('collapse',),
            'fields': (
                'location',
            ),
        }),
    )
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 拿到票的那一刻 朋友把我送到演唱会门口的那时候 等到真的等候入场的时候 心里各种复杂的情绪大概只有自己能明白吧 说...
    十二与七阅读 1,820评论 0 0
  • 雷蒙,我老婆。——亮针 穿上秋裤,整点白的。充电线。先给250,下回我开车,绕城看风水。出发前行李寄存前台,以免中...
    晴风村阅读 812评论 0 0
  • 你走过 空气中留下些许芬芳 我路过 内心里开始微微荡漾 我转身 看到了你远离的纤纤背影 你回头 我们便相识在宁静的小巷
    Ponky阅读 1,690评论 0 8