问题
My Problem:
I have a model that accepts DateTimeField
. The user enters this from the django-admin
. But, I cant get a way to get the user's local timezone. So my best shot is forcing the user to enter the date-time in UTC
. But for the users convenience, I do not want him/her to calculate each time the offset and then the time in UTC
. Django
doesn't seem to provide a way of doing this.
What I intend to do:
I want to create a custom widget
that will also let the user choose the timezone
along with entering the date
and time
. For this I am using the jQuery datetime picker.
I also intend to override
the django admin
form to have it use this widget of mine.
What I have tried so far:
<!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>
There isnt any action
or method
because I don't want this widget to post
anything anywhere. What it simply does is brings out a nice UI
in the browser and lets the user enter a date-time
and timezone
. So when the user clicks on Done
in this jQuery UI
the value appears in the textbox
of the form.
I seem to have hit a block. Cant think it out at all:
I cant figure out anyway that will let me reference
this input
by its id
or name
inside my widgets.py
file. widgets.py
file is the file where I intend to define
the custom widget
by extending Widget
from *django.forms.widgets*
. I read through the docs and figured out that Widget
class has two methods of particular importance in this case. The render
and value_from_data_dict
methods. The former to render the html template and the latter to extract that value from the data dict. (I may be wrong.) But I cant figure out any way to link these two parts of my code. I need help.
Update:
I worked on it but its not working. Heres what I have done till now:
ui/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))
And here is 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"}
]
});
});
});
What I am stuck at is how do I invoke the javascript from tz_widget.js? In the django admin there is no dropdown or anything. So I am sure the javascript function isnt being called. How can I call it? I dont think I can render it along the html unicode string. Any ideas? I have been at this all night. Need some help please.
回答1:
I think you can create a more generic widget.
First, separate your js, html and media for create a unique widget.
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))"
Now in your admin class, try this:
class YourClassAdmin(admin.ModelAdmin):
class Media:
css = {
"all": ("my_styles.css",)
}
js = ("my_code.js",)
formfield_overrides = {
models.DateTimeField : {'widget': DatTimeField()},
}
If you want to customize your widgets, I suggest you to see the TinyMce widget Code. I know it's a way different but this code helped me to develop my own widgets (https://github.com/aljosa/django-tinymce/tree/master/tinymce)
Django docs is also helpful: https://docs.djangoproject.com/en/1.5/ref/forms/widgets/
来源:https://stackoverflow.com/questions/17584532/how-to-create-a-custom-date-time-widget-for-the-django-admin