Способ изменения времени по умолчанию во время всплывающего окна Django [дубликат]

Интересно, что ни один из ответов на этой странице не упоминает два крайних случая, надеюсь, никто не возражает, если я их добавлю:

Случай с краем # 1: одновременный доступ к Словарю

Родовые словари в .NET не являются потокобезопасными, а иногда могут бросать NullReference или даже (чаще) a KeyNotFoundException при попытке получить доступ к ключу из двух параллельных потоков. Исключение в этом случае является довольно ошибочным.

Случай с краем # 2: небезопасный код

Если код NullReferenceException задан кодом unsafe, вы можете посмотреть на переменные указателя , и проверьте их на IntPtr.Zero или что-то в этом роде. Это одно и то же («исключение нулевого указателя»), но в небезопасном коде переменные часто переводятся в типы значений / массивы и т. Д., И вы ударяете головой о стену, задаваясь вопросом, как тип значения может исключение.

(Еще одна причина для небезопасного использования небезопасного кода, если вам это нужно)

8
задан JCotton 18 May 2011 в 03:35
поделиться

6 ответов

У Криса отличный ответ. В качестве альтернативы вы можете сделать это, используя только 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);
12
ответ дан nik_m 24 August 2018 в 21:57
поделиться

Я пошел с гораздо более простым подходом, и это сработало для меня. Я просто добавил варианты своей модели, используя следующий код:

class Class(Model): program = ForeignKey('Program') time_of_the_day = TimeField(choices=( (datetime.datetime.strptime('7:00 am', "%I:%M %p").time(), '7:00 am'), (datetime.datetime.strptime('8:00 am', "%I:%M %p").time(), '8:00 am'), (datetime.datetime.strptime('9:00 am', "%I:%M %p").time(), '9:00 am'), (datetime.datetime.strptime('6:00 pm', "%I:%M %p").time(), '6:00 pm'), (datetime.datetime.strptime('7:00 pm', "%I:%M %p").time(), '7:00 pm'), (datetime.datetime.strptime('8:00 pm', "%I:%M %p").time(), '8:00 pm'), (datetime.datetime.strptime('9:00 pm', "%I:%M %p").time(), '9:00 pm'),
))

Надеюсь, что это поможет

1
ответ дан Bit68 24 August 2018 в 21:57
поделиться

Подкласс 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)

Секретный соус находится в 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 + "'));");

Просто добавьте / удалите / измените этот бит javascript на контент вашего сердца.

Наконец, присоедините свой новый виджет к любым типам DateTimeFields, которые вам нравятся. Лучше всего для этого, вероятно, будет атрибут formfield_overrides на ModelAdmin:

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.DateTimeField: {'widget': MyAdminSplitDateTime},
    }
10
ответ дан Chris Pratt 24 August 2018 в 21:57
поделиться

Лучшее решение. После чтения 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);

Затем добавьте этот код в файл javascript в «static // time-shortcuts.js» и добавьте Meta к вашей модели администратора:

from django.contrib import admin
from .models import MyModel

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    class Media:
        js = [
            '<myapp>/time-shortcuts.js',
        ]
0
ответ дан Matt Harasymczuk 24 August 2018 в 21:57
поделиться

Переопределение JS с помощью функции DateTimeShortcuts.overrideTimeOptions работает только с одной формой (ошибка: изменение времени в дочерней модели влияет на родительскую модель, поэтому вы не можете изменить поле времени в форме дочерней модели этим виджетами )

Если вы хотите использовать пользовательские параметры времени со встроенными линиями:

в /static/admin/js/admin/DateTimeShortcuts.js заменить:

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 + "'));");

:

for(j=6;j<=23;j++){
    quickElement("a", quickElement("li", time_list, ""), j+":00", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1," + j + ",0,0,0).strftime('" + time_format + "'));");
}
1
ответ дан temasso 24 August 2018 в 21:57
поделиться

Я попытался использовать этот метод и обнаружил, что вышеупомянутый javascript не работал, когда в форме присутствовало несколько datetime.

вот что я сделал.

В разделе ModelAdmin Я добавил:

class Media:
    js = ('js/clock_time_selections.js',)

, затем в файле 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);
});

Примечание: мне пришлось вставить документ document.ready, потому что я обнаружил, что не могу контролировать, где сценарий был включен в страницу (кажется, он загружен до файлов js-файла по умолчанию).

4
ответ дан warath-coder 24 August 2018 в 21:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: