Django:如何更改AdminTimeWidget的选择

Mer*_*moz 11 django django-forms django-admin

AdminTimeWidget一个在管理渲染DateTimeField显示一个时钟图标,当你点击你的选择:"现在午夜6:00中午".

如何将这些选择更改为"16h 17h 18h"?

Bri*_*her 13

克里斯有一个很好的答案.作为替代方案,您可以使用javascript执行此操作.将以下javascript放在您想要不同时间选项的页面上.

DateTimeShortcuts.overrideTimeOptions = function () {
    // Find the first time element
    timeElement = django.jQuery("ul.timelist li").eq(0).clone();
    originalHref = timeElement.find('a').attr('href');

    // remove all existing time elements
    django.jQuery("ul.timelist li").remove();

    // add new time elements representing those you want
    var i=0;
    for (i=0;i<=23;i++) {
        // use a regular expression to update the link
        newHref = originalHref.replace(/Date\([^\)]*\)/g, "Date(1970,1,1," + i + ",0,0,0)");
        // update the text for the element
        timeElement.find('a').attr('href', newHref).text(i+"h");
        // Add the new element into the document
        django.jQuery("ul.timelist").append(timeElement.clone());
    }
}

addEvent(window, 'load', DateTimeShortcuts.overrideTimeOptions);
Run Code Online (Sandbox Code Playgroud)


Chr*_*att 10

子类AdminTimeWidget包含一个修改过的DateTimeShortcuts.js(在一秒内得到它),然后子类AdminSplitDateTime包含你的子类MyAdminTimeWidget而不是默认的Django:

from django.contrib.admin.widgets import AdminTimeWidget
from django.conf import settings

class MyAdminTimeWidget(AdminTimeWidget):
    class Media:
        js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js",
              settings.MEDIA_URL + "js/admin/DateTimeShortcuts.js")

class MyAdminSplitDateTime(AdminSplitDateTime):
    def __init__(self, attrs=None):
        widgets = [AdminDateWidget, MyAdminTimeWidget]
        forms.MultiWidget.__init__(self, widgets, attrs)
Run Code Online (Sandbox Code Playgroud)

秘密酱是在django/contrib/admin/media/js/admin/DateTimeShortcuts.js.这是创建要修改的列表的原因.复制此文件并将其粘贴到项目的site_media/js/admin目录中.您需要修改的相关代码位于第85-88行:

quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().strftime('" + time_format + "'));");
quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,0,0,0,0).strftime('" + time_format + "'));");
quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,6,0,0,0).strftime('" + time_format + "'));");
quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,12,0,0,0).strftime('" + time_format + "'));");
Run Code Online (Sandbox Code Playgroud)

只需添加/删除/修改javascript的这一点就可以了解您的内容.

最后,将您的新窗口小部件附加到您喜欢的任何DateTimeField.你最好的选择可能是以下formfield_overrides属性ModelAdmin:

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.DateTimeField: {'widget': MyAdminSplitDateTime},
    }
Run Code Online (Sandbox Code Playgroud)


war*_*der 5

我尝试使用此方法,发现当表单上存在多个日期时间时,上述 javascript 不起作用。

这是我所做的。

在我的 ModelAdmin 部分中,我添加了:

class Media:
    js = ('js/clock_time_selections.js',)
Run Code Online (Sandbox Code Playgroud)

然后在js文件中:

$('document').ready(function () {
    DateTimeShortcuts.overrideTimeOptions = function () {
        var clockCount = 0;
        console.log('ready');
        $('ul.timelist').each(function () {
            var $this = $(this);
            var originalHref = $this.find('a').attr('href');
            console.log(originalHref);
            $this.find('li').remove();
            for (i=8; i <= 20; i++) {
                var newLink = '<li><a href="javascript:DateTimeShortcuts.handleClockQuicklink('+ clockCount + ', ' + i
                    + ');"> ' + i + ':00h</a></li>';
                $this.append(newLink);
            }
            //console.log($this.html());

            clockCount++;
        });
    };

    addEvent(window, 'load', DateTimeShortcuts.overrideTimeOptions);
});
Run Code Online (Sandbox Code Playgroud)

注意:我不得不放入一个 document.ready 因为我发现我无法控制脚本在页面中的位置(似乎在默认日历 js 文件之前加载)。


Mat*_*zuk 5

有更好的解决方案。阅读DateTimeShortcuts.js后,可以简化为:

(function ($) {
    $(document).ready(function () {

        DateTimeShortcuts.clockHours.default_ = [];

        for (let hour = 8; hour <= 20; hour++) {
            let verbose_name = new Date(1970, 1, 1, hour, 0, 0).strftime('%H:%M');
            DateTimeShortcuts.clockHours.default_.push([verbose_name, hour])
        }

    });
})(django.jQuery);
Run Code Online (Sandbox Code Playgroud)

然后将此代码添加到“static//time-shortcuts.js”中的 javascript 文件中,并将 Meta 添加到您的管理模型中:

from django.contrib import admin
from .models import MyModel

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    class Media:
        js = [
            '<myapp>/time-shortcuts.js',
        ]
Run Code Online (Sandbox Code Playgroud)