Django中的日期处理注意事项和自定义时间格式转换
Django中的日期处理注意事项和自定义时间格式转换
模型视图表单路由
# 模型表示
class EventContent(models.Model):
# ······
end_time = models.DateTimeField(default=timezone.now, verbose_name='事件结束时间')
# ······
# 表单
class EventContentForm(forms.ModelForm):
class Meta:
model = EventContent
fields = ('end_time', )
# 路由
urlpatterns = [
url(r'^event/create/$', CreateEvent.as_view(), name='event_create'),
# ······
]
# 视图
class CreateEvent(View):
def get(self, request):
event_content_form = EventContentForm()
return render(request, 'event_create.html',
{
'event_content_form': event_content_form,
})
def post(self, request):
event_content_form = EventContentForm(request.POST, request.FILES)
print(event_content_form)
if event_content_form.is_valid():
print('保存数据库')
return render(request, 'event_create.html',
{
'event_content_form': event_content_form,
})
前端页面
<link rel="stylesheet" href="{% static 'css/bootstrap-datetimepicker/bootstrap-datetimepicker.min.css' %}" />
<div class="form-group">
<label for="{{ event_content_form.end_time.id_for_label }}">{{ event_content_form.end_time.label }}</label>
<div class="input-append date form_datetime" data-date="">
<input type="text" class="form-control" name="end_time"
id="{{ event_content_form.end_time.id_for_label }}"
placeholder="事件需在该时间前完成"
value="{% if event_content_form.end_time.value %}{{ event_content_form.end_time.value }}{% endif %}"/>
<span class="add-on"><i class="icon-remove"></i></span>
<span class="add-on"><i class="icon-calendar"></i></span>
</div>
<p><div class="text-warning"><small>{{ event_content_form.end_time.errors }}</small></div></p>
</div>
<script src="{% static 'js/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js' %}"></script>
<script src="{% static 'js/bootstrap-datetimepicker/bootstrap-datetimepicker.zh-CN.js' %}"></script>
<script type="text/javascript">
$(".form_datetime").datetimepicker({
//format: "yyyy年mm月dd日 hh:ii:ss", // 格式化 五月 22, 2018, 2:37 p.m.(后面排除错误)
language: 'zh-CN', // 需要中文支持 .zh-CN.js
autoclose: true,
todayBtn: true,
todayHighlight: true,
startDate: "2018-05-06 09:00", // 开始日期
minuteStep: 10,
forceParse: false, // 否强制解析输入框中的值关闭
});
</script>
问题处理过程
当访问 http://127.0.0.1:8000/event/create/ ,会渲染时间表单
后端时间格式:五月 22, 2018, 4:14 p.m.
{{ event_content_form.end_time.value }}
渲染出来的结果是五月 22, 2018, 4:14 p.m.
也就是后台时间默认的格式
如果我们直接提交,五月 22, 2018, 4:14 p.m.
是验证不通过的
后端print打印的html代码为:
<tr>
<th><label for="id_end_time">事件结束时间:</label></th>
<td>
<ul class="errorlist"><li>输入一个有效的日期/时间。</li></ul>
<input type="text" name="end_time" value="五月 22, 2018, 4:14 p.m." required id="id_end_time" />
<input type="hidden" name="initial-end_time" value="五月 22, 2018, 4:14 p.m." id="initial-id_end_time" /></td></tr>
前端时间格式:2018-05-23 09:00
点击事件控件修改时间,会修改成默认的格式2018-05-23 09:00
然后提交,未出现错误,表明时间格式2018-05-23 09:00
正确,提交成功
但是页面渲染的最初结果从五月 22, 2018, 4:14 p.m.
格式的时间变成2018-05-23 09:00
这样格式,感觉有点奇怪。
自定义时间格式转换测试
后端时间格式:2018年05月22日 16:54:08
修改settings.py文件
修改为自己想显示的格式
# USE_L10N = True
USE_L10N = False
DATE_FORMAT = 'Y年m月d'
DATETIME_FORMAT = 'Y年m月d日 H:i:s'
访问链接渲染{{ event_content_form.end_time.value }}
出来的时间格式2018年05月22日 16:54:08
,也就是和后端相同的显示。
前端时间格式:2018年05月23日 09:00:00
修改时间控件js
<script type="text/javascript">
$(".form_datetime").datetimepicker({
format: "yyyy年mm月dd日 hh:ii:ss", // 格式化 五月 22, 2018, 2:37 p.m.(后面排除错误)
language: 'zh-CN', // 需要中文支持 .zh-CN.js
autoclose: true,
todayBtn: true,
todayHighlight: true,
startDate: "2018-05-06 09:00", // 开始日期
minuteStep: 10,
forceParse: false, // 否强制解析输入框中的值关闭
});
</script>
然后通过时间控件选择时间2018年05月23日 09:00:00
,提交也会出问题
前端时间格式:2018-05-23 10:00:00
修改时间控件的格式化
<script type="text/javascript">
$(".form_datetime").datetimepicker({
//format: "yyyy年mm月dd日 hh:ii:ss",
format: "yyyy-mm-dd hh:ii:ss", // 格式化 必须使用这样的格式,才能提交成功,或者不要这一项
language: 'zh-CN', // 需要中文支持 .zh-CN.js
autoclose: true,
todayBtn: true,
todayHighlight: true,
startDate: "2018-05-06 09:00", // 开始日期
minuteStep: 10,
forceParse: false, // 否强制解析输入框中的值关闭
});
</script>
此时访问链接显示的格式同样是2018年05月22日 17:03:24
,使用时间控件选择一个时间2018-05-23 10:00:00
,提交没有出错
经过多次验证,表明前后端传递时间的格式为2018-05-23 10:00:00
才能提交成功
最终结果
后端设置时间格式:'Y-m-d H:i:s'
为了前后端时间显示统一,修改后端时间的显示格式
# USE_L10N = True
USE_L10N = False
DATE_FORMAT = 'Y-m-d'
DATETIME_FORMAT = 'Y-m-d H:i:s'
注意事项:如果USE_L10N设置为了True,那么语言环境规定的格式具有更高的优先级并将被应用,即DATE_FORMAT不生效。
这里可用的格式化字符串的其他写法参见Django官方文档:
https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#date;
即后端显示时间格式变为2018-05-26 15:58:28
刷新后台,显示新格式的时间。
前端设置时间格式:"yyyy-mm-dd hh:ii:ss"
修改时间控件
<script type="text/javascript">
$(".form_datetime").datetimepicker({
//format: "yyyy年mm月dd日 hh:ii:ss",
format: "yyyy-mm-dd hh:ii:ss", // 格式化 必须使用这样的格式,才能提交成功,或者不要这一项
language: 'zh-CN', // 需要中文支持 .zh-CN.js
autoclose: true,
todayBtn: true,
todayHighlight: true,
startDate: "2018-05-06 09:00", // 开始日期
minuteStep: 10,
forceParse: false, // 否强制解析输入框中的值关闭
});
</script>
可通传递时间格式:2018-05-24 18:00:17
模板
<div class="form-group">
<label for="{{ event_content_form.end_time.id_for_label }}">{{ event_content_form.end_time.label }}</label>
<div class="input-append date form_datetime" data-date="">
<input type="text" class="form-control" name="end_time"
id="{{ event_content_form.end_time.id_for_label }}"
placeholder="事件需在该时间前完成"
value="{% if event_content_form.end_time.value %}{{ event_content_form.end_time.value }}{% endif %}"/>
<span class="add-on"><i class="icon-remove"></i></span>
<span class="add-on"><i class="icon-calendar"></i></span>
</div>
<p><div class="text-warning"><small>{{ event_content_form.end_time.errors }}</small></div></p>
</div>
前端格式化时间
另外在Django页面渲染的时候,html页面从数据库中读出DateTimeField
字段时,显示的时间格式和数据库中存放的格式不一致,另外一个解决办法:可以在页面格式化时间,添加{{ event_content_form.end_time.value|date:"Y年m月d日 H:i:s" }}
类似的过滤器。之后刷新页面,即可正常显示。但这个当时不适合表单提交
不知哪位同学有高见,可以指出。