django - 如何在 Django Form 中将 2 个日期时间字段分解为 1 个日期和 2 个时间?
问题描述
好的,所以我正在尝试预订时段(如活动/预订)。
#models.py
class BookingSlot(models.Model):
start_time = models.DateTimeField("Start Time")
end_time = models.DateTimeField("End Time")
location = models.ForeignKey(Court, on_delete=models.CASCADE)
如您所见,该模型有 2 个日期时间字段。我想制作一个用于创建预订空档的表格,该表格只包含一个日期和两次(假设它是同一天)。我知道我可以改变我的模型,但这会产生一些问题。
#forms.py
class BookingSlotForm(ModelForm):
class Meta:
model = BookingSlot
fields = ['start_time', 'end_time', 'location']
我想知道是否有一种方法可以编辑我的 forms.py 来做到这一点。看起来这很简单,我只是不确定如何为它制定一个问题。
#views.py
class CreateBookingForm(CreateView):
template_name = 'app_book/create_bookings.html'
form_class = BookingSlotForm
success_message = 'Booking slot created'
解决方案
为此,您需要:
DateTimeField
在您的模型表单中不包含模型- 相反,包括一个表单
DateField
和两个TimeField
s DateTimeField
保存时,通过组合表单字段来填充新实例
所以是这样的:
class BookingSlotForm(ModelForm):
class Meta:
model = BookingSlot
fields = ['location']
slot_date = forms.DateField()
start_time = forms.TimeField()
end_time = forms.TimeField()
def save(self, commit=True):
slot = super(BookingSlotForm, self).save(commit=False)
slot.start_time = datetime.combine(self.cleaned_data['slot_date'], self.cleaned_data['start_time'])
slot.end_time = datetime.combine(self.cleaned_data['slot_date'], self.cleand_data['end_time'])
if commit:
slot.save()
return slot
如果您的表单有 m2m 字段,您还需要save_m2m()
在保存实例后调用该方法 when commit=True
。而且我忽略了结束时间在开始时间之后的验证 - 这是您clean()
在模型表单上使用自定义方法所做的事情,因为它需要比较两个字段的值。
如果您想使用这样的东西进行编辑,您还需要覆盖表单类的__init__
方法以从实例中复制正确的值(如果有)。看起来像这样:
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance')
if instance:
initial = kwargs.get('initial', {})
# Here I'm not considering the possibility of the slot having different dates
initial['slot_date'] = instance.start_time.date()
initial['start_time'] = instance.start_time.time()
initial['end_time'] = instance.end_time.time()
kwargs['initial'] = initial
super(BookingSlotForm, self).__init__(*args, **kwargs)