Django Widgets

2017-10-31  本文已影响0人  manbug

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',
            ),
        }),
    )
上一篇下一篇

猜你喜欢

热点阅读