Python 在ModelForm中将datetime字段仅显示为小时和分钟(未显示日期)

Python 在ModelForm中将datetime字段仅显示为小时和分钟(未显示日期),python,django,Python,Django,我正在Django上制作日历。当用户单击日历上的某一天时,他将被重定向到CreateEventForm,在该窗体中,他可以创建在他单击的那一天(所选日期)发生的事件。为了避免用户输入所选日期的麻烦,我使用get_form_kwargs()将所选日期发送到表单,并预先填充开始时间和结束时间字段。这样,他只需要输入事件开始时间和结束时间的小时和分钟 我的问题 当前,整个“%Y-%m-%dT%H:%m”格式如下所示: 我只想显示%H:%M。但我想确保datetime对象仍然包含日期;除了不会向最终用户

我正在Django上制作日历。当用户单击日历上的某一天时,他将被重定向到CreateEventForm,在该窗体中,他可以创建在他单击的那一天(所选日期)发生的事件。为了避免用户输入所选日期的麻烦,我使用get_form_kwargs()将所选日期发送到表单,并预先填充开始时间和结束时间字段。这样,他只需要输入事件开始时间和结束时间的小时和分钟

我的问题

当前,整个“%Y-%m-%dT%H:%m”格式如下所示:

我只想显示%H:%M。但我想确保datetime对象仍然包含日期;除了不会向最终用户显示之外,如下所示:

我曾尝试使用表单小部件格式化datetime对象,但它似乎不起作用。当我将字段格式化为“%H:%M”时,该字段显示如下:

表格

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
    小部件。日期保存在数据库中,当您将其取回时,我们在我的第一个版本中编辑的
    初始
    输入格式
    字段可能不会影响对用户的渲染。我认为在小部件上设置
    格式
    可能适用于将对象从