如何为django管理员创建自定义日期时间窗口小部件?

时间:2013-07-11 03:23:38

标签: python django django-widget custom-widgets

我的问题:

我有一个接受DateTimeField的模型。用户从django-admin输入此内容。但是,我无法找到获取用户本地时区的方法。所以我的最佳镜头是强迫用户在UTC中输入日期时间。但为了方便用户,我不希望他/她每次计算偏移量,然后计算UTC中的时间。 Django似乎没有提供这样做的方法。

我打算做什么:

我想创建一个custom widget,也可以让用户选择timezone并输入datetime。为此,我使用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>

没有任何actionmethod,因为我不希望这个小部件在任何地方post。它只是在浏览器中显示一个不错的UI,并允许用户输入date-timetimezone。因此,当用户点击此Done中的jQuery UI时,该值会显示在textbox

form.

我好像遇到了障碍。不能这么想:

无论如何我无法弄明白,reference input id name来自我widgets.py文件中的widgets.py define。通过从custom widget扩展Widget*django.forms.widgets*文件是我打算Widget render的文件。我通读docs并发现value_from_data_dict类在这种情况下有两种特别重要的方法。 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()}, } 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)) 方法。前者用于呈现html模板,后者用于从数据dict中提取该值。 (我可能错了。)但我无法找出任何方法来链接我的代码的这两部分。我需要帮助。

更新

我努力了,但它不起作用。以下是我迄今所做的事情:

UI / admin.py

$(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"}
        ]
    });       
});
});

widgets.py

{{1}}

这是 tz_widget.js:

{{1}}

我遇到的是如何从tz_widget.js调用javascript?在django管理员中没有下拉或任何东西。所以我确信javascript函数没有被调用。我怎么称呼它?我不认为我可以沿着html unicode字符串渲染它。有任何想法吗?我整晚都在这。需要一些帮助。

1 个答案:

答案 0 :(得分:0)

我认为你可以创建一个更通用的小部件。

首先,将js,html和媒体分开以创建一个独特的小部件。

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/