Python 在ModelForm中将datetime字段仅显示为小时和分钟(未显示日期)
我正在Django上制作日历。当用户单击日历上的某一天时,他将被重定向到CreateEventForm,在该窗体中,他可以创建在他单击的那一天(所选日期)发生的事件。为了避免用户输入所选日期的麻烦,我使用get_form_kwargs()将所选日期发送到表单,并预先填充开始时间和结束时间字段。这样,他只需要输入事件开始时间和结束时间的小时和分钟 我的问题 当前,整个“%Y-%m-%dT%H:%m”格式如下所示: 我只想显示%H:%M。但我想确保datetime对象仍然包含日期;除了不会向最终用户显示之外,如下所示: 我曾尝试使用表单小部件格式化datetime对象,但它似乎不起作用。当我将字段格式化为“%H:%M”时,该字段显示如下: 表格Python 在ModelForm中将datetime字段仅显示为小时和分钟(未显示日期),python,django,Python,Django,我正在Django上制作日历。当用户单击日历上的某一天时,他将被重定向到CreateEventForm,在该窗体中,他可以创建在他单击的那一天(所选日期)发生的事件。为了避免用户输入所选日期的麻烦,我使用get_form_kwargs()将所选日期发送到表单,并预先填充开始时间和结束时间字段。这样,他只需要输入事件开始时间和结束时间的小时和分钟 我的问题 当前,整个“%Y-%m-%dT%H:%m”格式如下所示: 我只想显示%H:%M。但我想确保datetime对象仍然包含日期;除了不会向最终用户
class EventForm(ModelForm):
class Meta:
model = Event
widgets = {
'start_time': DateInput(attrs={'type': 'datetime-local'}, format='%H:%M'),
'end_time': DateInput(attrs={'type': 'datetime-local'}, format='%H:%M'),
}
fields = '__all__'
def __init__(self, selected_date, *args, **kwargs):
super(EventForm, self).__init__(*args, **kwargs)
self.fields['start_time'].initial = selected_date
self.fields['end_time'].initial = selected_date
self.fields['start_time'].input_formats = ('%H:%M',)
self.fields['end_time'].input_formats = ('%H:%M',)
class Event(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
start_time = models.DateTimeField()
end_time = models.DateTimeField()
def get_absolute_url(self):
return reverse('cal:calendar')
class EventCreateView(generic.CreateView):
model = Event
template_name = 'cal/event.html'
form_class = EventForm
def get_form_kwargs(self):
kwargs = super(EventCreateView, self).get_form_kwargs()
selected_date_str = self.request.GET.get('date', None)
selected_date = datetime.strptime(selected_date_str, '%Y-%m-%d')
kwargs.update({'selected_date': selected_date})
return kwargs
class EventUpdateView(generic.UpdateView):
model = Event
template_name = 'cal/event.html'
form_class = EventForm
型号
class EventForm(ModelForm):
class Meta:
model = Event
widgets = {
'start_time': DateInput(attrs={'type': 'datetime-local'}, format='%H:%M'),
'end_time': DateInput(attrs={'type': 'datetime-local'}, format='%H:%M'),
}
fields = '__all__'
def __init__(self, selected_date, *args, **kwargs):
super(EventForm, self).__init__(*args, **kwargs)
self.fields['start_time'].initial = selected_date
self.fields['end_time'].initial = selected_date
self.fields['start_time'].input_formats = ('%H:%M',)
self.fields['end_time'].input_formats = ('%H:%M',)
class Event(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
start_time = models.DateTimeField()
end_time = models.DateTimeField()
def get_absolute_url(self):
return reverse('cal:calendar')
class EventCreateView(generic.CreateView):
model = Event
template_name = 'cal/event.html'
form_class = EventForm
def get_form_kwargs(self):
kwargs = super(EventCreateView, self).get_form_kwargs()
selected_date_str = self.request.GET.get('date', None)
selected_date = datetime.strptime(selected_date_str, '%Y-%m-%d')
kwargs.update({'selected_date': selected_date})
return kwargs
class EventUpdateView(generic.UpdateView):
model = Event
template_name = 'cal/event.html'
form_class = EventForm
视图
class EventForm(ModelForm):
class Meta:
model = Event
widgets = {
'start_time': DateInput(attrs={'type': 'datetime-local'}, format='%H:%M'),
'end_time': DateInput(attrs={'type': 'datetime-local'}, format='%H:%M'),
}
fields = '__all__'
def __init__(self, selected_date, *args, **kwargs):
super(EventForm, self).__init__(*args, **kwargs)
self.fields['start_time'].initial = selected_date
self.fields['end_time'].initial = selected_date
self.fields['start_time'].input_formats = ('%H:%M',)
self.fields['end_time'].input_formats = ('%H:%M',)
class Event(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
start_time = models.DateTimeField()
end_time = models.DateTimeField()
def get_absolute_url(self):
return reverse('cal:calendar')
class EventCreateView(generic.CreateView):
model = Event
template_name = 'cal/event.html'
form_class = EventForm
def get_form_kwargs(self):
kwargs = super(EventCreateView, self).get_form_kwargs()
selected_date_str = self.request.GET.get('date', None)
selected_date = datetime.strptime(selected_date_str, '%Y-%m-%d')
kwargs.update({'selected_date': selected_date})
return kwargs
class EventUpdateView(generic.UpdateView):
model = Event
template_name = 'cal/event.html'
form_class = EventForm
模板
{% extends 'cal/base.html' %}
{% load crispy_forms_tags %}
{% block title %}
Event
{% endblock %}
{% block content %}
<div class="clearfix">
<a class="btn btn-info left" href="{% url 'cal:calendar' %}"> Calendar </a>
</div>
<div class="container">
<form method="post">
<div class="form-group">
{% csrf_token %}
{% if form.instance.pk %}
<h3 class="center">{{ form.instance.start_time }}</h3>
{% else %}
<h3 class="center">{{selected_date}}</h3>
{% endif %}
<div class="col-4">{{ form.title | as_crispy_field }}</div>
<div class="col-4">{{ form.description | as_crispy_field }}</div>
<div class="col-4">{{ form.start_time | as_crispy_field }}</div>
<div class="col-4">{{ form.end_time | as_crispy_field }}</div>
{% if form.instance.pk %}
<a href="{% url 'cal:event_delete' pk=event.pk %}" class="btn btn-danger"> Delete </a>
{% endif %}
<button type="submit" class="btn btn-info"> Submit </button>
</div>
</form>
{% endblock %}
{%extends'cal/base.html%}
{%load crispy_forms_tags%}
{%block title%}
事件
{%endblock%}
{%block content%}
{%csrf_令牌%}
{%if form.instance.pk%}
{{form.instance.start_time}
{%else%}
{{所选日期}
{%endif%}
{{form.title}as_crispy_field}
{{form.description}as_crispy_field}
{{form.start_time}as_crispy_field}
{{form.end_time}as_crispy_field}
{%if form.instance.pk%}
{%endif%}
提交
{%endblock%}
clean
方法以处理创建datetime
对象DateTimeInput
小部件所选日期
class事件形式(ModelForm):
start_time=forms.DateTimeField(必需=True,输入_格式=['%H:%M'],localize=True,widget=forms.DateTimeInput)
end_time=forms.DateTimeField(必需=True,输入_格式=['%H:%M'],localize=True,widget=forms.DateTimeInput)
所选日期=forms.DateField(必需=True)
类元:
模型=事件
字段=[“标题”、“说明”、“开始时间”、“结束时间”、“选定日期”]
定义初始日期(自、选定日期、*args、**kwargs):
super(EventForm,self)。\uuuuu init\uuuuu(*args,**kwargs)
self.fields['selected_date'].initial=selected_date
def清洁(自清洁):
结束时间=自清理数据['结束时间']
结束时间=结束时间.replace(年份=自清理的数据['selected_date'].year)
结束时间=结束时间.replace(月=自清理的数据['selected_date'].month)
结束时间=结束时间.replace(天=自清理数据['selected_date'].day)
开始时间=自清理数据['start\u time']
开始时间=开始时间.replace(年份=自清理的数据['selected\u date'].year)
开始时间=开始时间.replace(月=自清理的数据['selected_date'].month)
开始时间=开始时间.replace(天=自清理的数据['selected\u date'].day)
返回self.cleaned_data.update({'end_time':end_time,'start_time':start_time})
要将所选日期发布到您的EventCreateView
(当用户从模板提交表单时发生),请将以下内容添加到模板中:
<form>
...
<input id="selected_date" type="hidden" name="selected_date" value="{{ selected_date }}">
...
</form>
...
...
与自动从请求中提取标题
和说明
并保存到表单的方式相同,Django将提取所选日期。发生这种情况是因为和。因此,您可以在clean()
方法中使用selected\u date
字段中的selected\u date
值,然后使用它创建完整的datetime
对象,并将它们传递回表单框架,表单框架将为您保存它们
更多关于隐藏元素的信息可以找到
注意:这要求在用户填写完结束时间
和开始时间
后,在POST请求期间将所选日期
传递回。这是因为如果字符串匹配,Django的表单框架将自动获取该值。(如果需要帮助,请发布模板代码。)
我的更改依赖于Django表单的实现细节。国家:
表单子类的clean()方法可以执行需要访问多个表单字段的验证。您可以在此处进行检查,例如“如果提供了字段A,则字段B必须包含有效的电子邮件地址”。如果愿意,此方法可以返回一个完全不同的字典,该字典将用作已清理的\u数据
请同时发布您的视图。py.刚刚发布了视图。很抱歉尝试将
DateInput
小部件更改为DateTimeInput
,但保留相同的格式参数。另请参见以下答案:。也许您也有同样的问题(您使用的是格式
)?在最后两行中,我不确定您的意思是:self.fields['end\u time'].initial=selected\u date.strftime('%H:%m'),因为没有strftime,我在/event/new/datetime.datetime'对象处得到TypeError是不可调用的。如果我使用strftime,它可以工作,但是当我保存对象时,日期会恢复为默认的1900-01-01。是的,这是我代码中的语法问题。你能说出你希望它被保存为什么吗?请尝试我的答案的更新版本,其中包括DateTimeInput
小部件。日期保存在数据库中,当您将其取回时,我们在我的第一个版本中编辑的初始
和输入格式
字段可能不会影响对用户的渲染。我认为在小部件上设置格式
可能适用于将对象从