在Django管理界面字段中添加自定义JS
在一个Django应用中,我有一个这样的模型:
class Appointment(models.Model):
#some other fields
#address fields
zipcode=models.CharField(max_length=5)
address=models.CharField(max_length=120)
latitude=models.FloatField()
longitude=models.FloatField()
当我渲染一个预约时,我只是把一个标记放在指定的经度和纬度位置,并用地址作为文本,但我需要经度和纬度来做到这一点。
目前,经度和纬度需要在后台手动输入,但打开谷歌地图或开放街图,搜索地址并输入经度和纬度,这些工作不应该由人手动完成,所以我想通过谷歌地图的API来获取这些信息(这个过程叫做地理编码)。
理想情况下,我希望在地址旁边有一个“获取坐标”的按钮,按下后会开始一个地理编码请求,当地址明确时,会自动填写经度和纬度,并展示一个地图,用户点击正确的标记时就能填写坐标。
我知道怎么做,但不太确定该如何把这些代码和标记放到后台管理界面中。
我考虑过一些方法,但觉得这些方法不太自然,或者对这么简单的任务来说工作量太大:
- 把代码放在地址字段描述中,在从
admin.ModelAdmin
继承的类里的field_options
中 - 把所有与地址相关的内容放在一个单独的模型中,并使用一个自定义的
form
(还需要一个单独的模板) - 创建一个地址选择器小部件
- 使用GeoDjango
2 个回答
这里主要讨论的是客户端的标记和客户端的JavaScript。既然如此,使用一个专门处理这些内容的工具似乎是个不错的选择。我还建议你可以制作一个自定义的管理小部件。我自己也用过这种方法。根据客户端标记的大小,你甚至可以利用Django模板来渲染这个小部件。
另外,你也可以写一些不干扰页面的JavaScript,在页面加载后重新渲染那部分内容。用这种方法,你只需要在管理模型中用class Media:
来包含那个JavaScript文件就可以了。
这更像是伪代码,但能让你明白大概意思:
admin.py
class AppointmentAdmin(admin.ModelAdmin):
# ...
class Media:
from django.conf import settings
media_url = getattr(settings, 'MEDIA_URL', '/media')
js = [ media_url+'/admin/long-lat-render.js', ]
long-lat-render.js
// Written for jQuery
$(function(){
// on page load...
$('#_LongitudeTag').html('');
var getCoordButton = $('<button id="get-coords"></button>');
$('#_LongitudeTag').append(getCoordButton);
addGMap($('#_LongitudeTag').get(0));
});
function addGMap(element) {
// do whatevers
}
有几种方法可以做到这一点。你自己已经提到了一些。
一种选择是覆盖你管理后台的保存页面模板,然后在模板中添加所需的代码。你可以通过在你的ModelAdmin类中使用一个内部的Media类来添加所需的媒体文件、JavaScript、CSS等。这个Media类有两个不同的属性,一个是包含CSS样式表的元组,另一个是包含JavaScript文件的元组。
我个人觉得,在这种情况下,最好的选择是使用一个自定义的地址选择器小部件,就像你在不想采用的方法列表中提到的那样。