Как создать собственный виджет даты и времени для администратора 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/