Как создать собственный виджет даты и времени для администратора django?

Моя проблема:

У меня есть модель, которая принимает DateTimeField, Пользователь вводит это из django-admin, Но я не могу получить способ узнать местный часовой пояс пользователя. Так что мой лучший шанс - заставить пользователя ввести дату и время в UTC, Но для удобства пользователей я не хочу, чтобы он / она каждый раз вычислял смещение, а затем время в UTC, Django кажется, не обеспечивает способ сделать это.

Что я намерен сделать:

Я хочу создать custom widget это также позволит пользователю выбрать timezone наряду с входом в date а также time, Для этого я использую jQuery datetime picker. Я также намерен override django admin Форма, чтобы иметь это использовать мой виджет.

Что я уже пробовал:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title> - jsFiddle demo by ioncache</title>
    <script type='text/javascript' src='http://code.jquery.com/jquery-1.7.1.js'></script>
    <link rel="stylesheet" type="text/css" href="/css/normalize.css">
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
    <link rel="stylesheet" type="text/css" href="/css/result-light.css">
    <script type='text/javascript' src="https://raw.github.com/trentrichardson/jQuery-Timepicker-Addon/master/jquery-ui-timepicker-addon.js"></script>
    <link rel="stylesheet" type="text/css" href="https://raw.github.com/trentrichardson/jQuery-Timepicker-Addon/master/jquery-ui-timepicker-addon.css">
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/smoothness/jquery-ui.css">
    <style type='text/css'>
    </style>

    <script type='text/javascript'>//<![CDATA[
        $(window).load(function(){
        $(function() {
            $('#date-time-tz').datetimepicker({
            dateFormat: $.datepicker.RFC_2822,
            timeFormat: 'hh:mm:ss z',
            showTimezone: true,
            timezoneList: [
                {"value": "0", "label": "UTC"},
                {"value": "+60", "label": "FRANCE"},
                {"value": "+330", "label": "INDIA"},
                {"value": "-240", "label": "US EAST"},
                {"value": "-420", "label": "US SF"}
            ]
        });       
    });
    });//]]>  
    </script>

    </head>
        <body>
        <form name="time">
            <div style="margin: 15px;">
                <input id="date-time-tz" type="text" value="" name="date-time-tz">
                <input type="submit" value="Submit">
            </div>
        </form>
        </body>
</html>

Там нет никакого action или же method потому что я не хочу, чтобы этот виджет post что угодно где угодно. То, что он просто делает, это производит хороший UI в браузере и позволяет пользователю ввести date-time а также timezone, Поэтому, когда пользователь нажимает на Done в этом jQuery UI значение появляется в textbox из form.

Я, кажется, ударил блок. Не могу придумать это вообще

Я все равно не могу понять, что позволит мне reference этот input своим id или же name внутри моего widgets.py файл. widgets.py файл - это файл, в котором я собираюсь define custom widget расширяя Widget от *django.forms.widgets*, Я прочитал документы и понял, что Widget класс имеет два метода, имеющих особое значение в этом случае. render а также value_from_data_dict методы. Первый для отображения HTML-шаблона, а второй для извлечения этого значения из данных dict. (Я могу ошибаться.) Но я не могу придумать, как связать эти две части моего кода. Мне нужна помощь.

Обновить:

Я работал над этим, но это не работает. Вот что я сделал до сих пор:

щ / admin.py

class MyModelAdmin(admin.ModelAdmin):
    class Media:
        css = {
                "all": ("style/jquery-ui.css",
                        "style/jquery-ui-timepicker-addon.css",)
            }
        js = ("js/jquery-ui.js",
              "js/jquery-ui-timepicker-addon.js",
              "js/tz_widget.js",)

    formfield_overrides = {
            models.DateTimeField : {'widget': TimezoneDate()},
        }

widgets.py

DATE_FORMAT = "%m-%d-%y"

class TimezoneDate(forms.widgets.Widget):

    def __init__(self, attrs=None):
        super(TimezoneDate, self).__init__(attrs)

    def render(self, name, value, attrs=None):

        if value is None:
            vstr = ''
        elif hasattr(value, 'strftime'):
            vstr = datetime_safe.new_datetime(value).stftime(DATE_FORMAT)
        else:
            vstr = value
        id = "%s" % name
        args = \
            "<input type=\"text\" value=\"%s\" name=\"%s\" id=\"date_time_tz\" />" % \
            (vstr, name)

        return mark_safe(u"\n".join(args))

А вот и tz_widget.js:

$(window).load(function(){
    $(function() {
        $('#date-time-tz').datetimepicker({
        dateFormat: $.datepicker.RFC_2822,
        timeFormat: 'hh:mm:ss z',
        showTimezone: true,
        timezoneList: [
            {"value": "0", "label": "UTC"},
            {"value": "+60", "label": "FRANCE"},
            {"value": "+330", "label": "INDIA"},
            {"value": "-240", "label": "US EAST"},
            {"value": "-420", "label": "US SF"}
        ]
    });       
});
});

Я застрял в том, как мне вызвать javascript из tz_widget.js? В админке django нет ни выпадающего меню, ни чего-либо еще. Поэтому я уверен, что функция javascript не вызывается. Как я могу это назвать? Я не думаю, что смогу отрендерить его в строке html unicode. Есть идеи? Я был в этом всю ночь. Нужна помощь, пожалуйста.

1 ответ

Я думаю, что вы можете создать более общий виджет.

Во-первых, разделите ваши js, html и media для создания уникального виджета.

widgets.py

 class DatTimeField(forms.Textarea):
     def render(self, name, attrs = None):
         final_attrs = self.build_attrs(attrs,name=name)
         return "Here you have to return the html of your widget, for example: mark_safe(u'<input type=text %s value=%s class='your_css_class'/>' % (flatatt(final_attrs), value))"

Теперь в вашем классе администратора, попробуйте это:

class YourClassAdmin(admin.ModelAdmin): 
    class Media:
        css = {
            "all": ("my_styles.css",)
        }
        js = ("my_code.js",)

    formfield_overrides = {
        models.DateTimeField : {'widget': DatTimeField()},

    }

Если вы хотите настроить свои виджеты, я предлагаю вам увидеть код виджета TinyMce. Я знаю, что это немного по-другому, но этот код помог мне разработать свои собственные виджеты ( https://github.com/aljosa/django-tinymce/tree/master/tinymce)

Документы Django также полезны: https://docs.djangoproject.com/en/1.5/ref/forms/widgets/

Другие вопросы по тегам