如何在Leaflet地图上显示Wilaya、Commune名称而非对应ID
问题根因
你当前遇到的问题来自两个核心错误:
Even模型的外键关联写错了:commune字段当前关联的是Wilaya表,而非对应的Commune表,且外键定义行末尾缺少右括号- 后端返回的GeoJSON接口默认仅序列化外键ID,没有带出关联表的
name字段,前端只能拿到ID值展示
解决步骤
1. 修正Even模型代码
将models.py中Even类的代码替换为以下内容,修正外键关联和语法错误:
class Even(models.Model): name = models.CharField(max_length=20, default='Even') date = models.DateField(null=True, blank=True) wilaya = models.ForeignKey(Wilaya, on_delete=models.DO_NOTHING, null=True, blank=True) # 修正commune外键关联指向Commune表,补全括号 commune = models.ForeignKey(Commune, on_delete=models.DO_NOTHING, null=True, blank=True) geom = models.PointField(srid=4326, null=True, blank=True,) # 新增两个属性直接返回关联名称,方便序列化 @property def wilaya_name(self): return self.wilaya.name if self.wilaya else "无数据" @property def commune_name(self): return self.commune.name if self.commune else "无数据" def __str__(self): return self.name
修改完成后执行python manage.py makemigrations和python manage.py migrate完成数据库迁移。
2. 调整后端GeoJSON序列化配置
修改你对应even接口的序列化逻辑,将新增的wilaya_name、commune_name两个字段加入返回的properties中:
- 如果你用
django-geojson类库:序列化时指定properties=['name', 'date', 'wilaya_name', 'commune_name'] - 如果你用Django REST Framework:在序列化器中新增这两个字段的返回配置即可
修改完成后可以先直接访问{% url 'even' %}对应的接口地址,确认返回的JSON中每个feature的properties里已经包含wilaya_name和commune_name字段,值为对应名称。
3. 修改前端展示逻辑
替换map.html中弹窗内容的对应字段,将ID替换为名称字段:
var even = new L.GeoJSON.AJAX("{% url 'even' %}", { pointToLayer: function (feature, latlng) { return L.marker(latlng, { icon: L.icon({ iconUrl: "/static/img/icons/red.png", iconSize: [28, 32], iconAnchor: [12, 28], popupAnchor: [0, -25] }), title: feature.properties.name, riseOnHover: true }); }, onEachFeature: function (feature, layer) { var content = "<table class='table table-striped table-bordered table-condensed'>" + "<tr><th>名称</th><td>" + feature.properties.name + "</td></tr>" + "<tr><th>日期</th><td>" + feature.properties.date + "</td></tr></table>" + "<details><summary>查看更多详情</summary><table class='table table-striped table-bordered table-condensed'><tr><th>Commune</th><td>" + feature.properties.commune_name + "</td></tr>" + "<tr><th>Wilaya</th><td>" + feature.properties.wilaya_name + "</td></tr>" + "</table></details>"; layer.on({ click: function (e) { layer.bindPopup(content).openPopup(e.latlng); } }); } }).addTo(map);
内容的提问来源于stack exchange,提问作者Saliha Alger
相关产品推荐
相关产品推荐

