gpt4 book ai didi

python - 在 ModelForm 中仅将日期时间字段显示为小时和分钟(不显示日期)

转载 作者:行者123 更新时间:2023-12-01 00:15:42 26 4
gpt4 key购买 nike

我正在 Django 上构建日历。当用户单击日历上的某一天时,他会被重定向到 CreateEventForm,在其中他可以创建在他单击的当天 (selected_date) 发生的事件。为了让用户免去输入所选日期的麻烦,我使用 get_form_kwargs() 将 selected_date 发送到表单并预填充 start_time 和 end-time 字段。这样,他只需要输入事件的start_time和end_time的小时和分钟即可。

我的问题

目前,整个“%Y-%m-%dT%H:%M”格式显示如下:

enter image description here

我只想显示 %H:%M。但我想确保日期时间对象仍然包含日期;只是它不会显示给最终用户,如下所示:

enter image description here

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

enter image description here

表单

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 %}

最佳答案

  1. 重写 clean 方法来处理创建 datetime 对象
  2. 我很确定您需要一个 DateTimeInput 小部件
  3. 使用 selected_date 在表单上添加隐藏字段
class EventForm(ModelForm):
start_time = forms.DateTimeField(required=True, input_formats=['%H:%M'], localize=True, widget=forms.DateTimeInput)
end_time = forms.DateTimeField(required=True, input_formats=['%H:%M'], localize=True, widget=forms.DateTimeInput)
selected_date = forms.DateField(required=True)

class Meta:
model = Event
fields = ['title', 'description', 'start_time', 'end_time', 'selected_date']

def __init__(self, selected_date, *args, **kwargs):
super(EventForm, self).__init__(*args, **kwargs)
self.fields['selected_date'].initial = selected_date

def clean(self):

end_time = self.cleaned_data['end_time']
end_time = end_time.replace(year = self.cleaned_data['selected_date'].year)
end_time = end_time.replace(month = self.cleaned_data['selected_date'].month)
end_time = end_time.replace(day = self.cleaned_data['selected_date'].day)

start_time = self.cleaned_data['start_time']
start_time = start_time.replace(year = self.cleaned_data['selected_date'].year)
start_time = start_time.replace(month = self.cleaned_data['selected_date'].month)
start_time = start_time.replace(day = self.cleaned_data['selected_date'].day)

return self.cleaned_data.update({'end_time': end_time, 'start_time': start_time})

要将 selected_date 发布到您的 EventCreateView(当用户从​​您的模板提交表单时发生),请将以下内容添加到您的模板中:

<form>
...
<input id="selected_date" type="hidden" name="selected_date" value="{{ selected_date }}">
...
</form>

与从请求中自动提取titledescription并保存到表单中的方式相同,selected_date也将被提取由 Django .发生这种情况是因为 view you're using automatically gets the POST datapasses it to your form class 。因此,您可以在 clean() 方法中使用 hidden 字段中的 selected_date 值,然后我们用它来创建完整的 datetime 对象并将它们传回表单框架,表单框架将为您保存它们。

有关隐藏元素的更多信息,请参见 here .

注意:这要求您在 POST 请求期间,在用户填写 end_timestart_time 后,将 selected_date 传回。这是因为如果字符串匹配,Django 的表单框架将自动获取该值。 (如果您需要帮助,请发布您的模板代码。)

我的更改依赖于 Django 表单的实现细节。 docs for the clean method状态:

The form subclass’s clean() method can perform validation that requires access to multiple form fields. This is where you might put in checks such as “if field A is supplied, field B must contain a valid email address”. This method can return a completely different dictionary if it wishes, which will be used as the cleaned_data.

关于python - 在 ModelForm 中仅将日期时间字段显示为小时和分钟(不显示日期),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59347982/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com