将自定义JS添加到django管理员字段

tst*_*ner 8 python django user-interface google-maps django-admin

在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()
Run Code Online (Sandbox Code Playgroud)

当我渲染一个约会时,我只是将一个标记放在经度和纬度指定的位置,地址为文本,但是我需要经度和经度才能做到这一点.

目前,必须在管理员后端手动输入纬度和经度,但打开谷歌地图/ OSM,搜索地址并输入纬度和经度是不必手动完成的工作,所以我想要检索它通过Google Maps API(关键字地理编码).

理想情况下,我希望地址旁边有一个"获取坐标"按钮,当按下该按钮时,会启动地理编码请求,并在地址明确时填充纬度和经度,并在用户显示结果并填充坐标时填充地图点击右侧标记.

我知道该怎么做,但我不确定如何将标记和代码插入管理员后端.

我已经考虑过但不想做的一些事情,因为它们看起来并不自然,或者看起来对于这么简单的任务似乎太多了:

  • 将代码放在地址字段的描述中field_options,从一个派生自的类中admin.ModelAdmin
  • 将所有地址相关联在一个单独的模型中并使用自定义form(使用单独的模板)
  • 创建一个地址选择器小部件
  • 使用GeoDjango

T. *_*one 20

主要处理的是客户端标记和客户端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', ]
Run Code Online (Sandbox Code Playgroud)

长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
}
Run Code Online (Sandbox Code Playgroud)

  • 媒体文件夹是一个有效的文件夹,但我认为更好的STATIC_URL就像这样static_url = getattr(settings,'STATIC_URL','/ static /')js = [static_url +'path/to/my/custom/file.js',] (3认同)

Mar*_*ark 4

有几种方法可以做到这一点。您自己已经提到了一些。

一种选择是覆盖管理员中保存页面的模板,并将所需的代码添加到模板中。可以使用 ModelAdmin 类中的内部 Media 类添加所需的媒体、Javascript、Css 等。这个媒体类有两个不同的属性,一个带有 css 样式表的元组和一个带有 javascript 文件的元组

我认为就我自己而言,在这种情况下最好的选择是自定义地址选择器小部件,正如您已经在您不想这样做的方式列表中提到的那样。