我有一个表单,用于创建带有日期和时间的课程。我目前有验证器,以确保不能使用过去的日期,这很好地工作。但是,我无法想象验证器如何确保输入的时间不超过晚上11:59。我提供了我要实现的目标的摘要(我知道它无法按布局方式工作,它只是在提供上下文)。我会为此提供任何帮助。
forms.py
def validate_date1(value):
if value < timezone.now():
raise ValidationError('Date cannot be in the past')
def validate_date2(value):
if value < timezone.now():
raise ValidationError('Date cannot be in the past')
def present_date1(value):
if value > '11:59 pm':
raise ValidationError('Time cannot be past 11:59 pm')
def present_date2(value):
if value > '11:59 pm':
raise ValidationError('Time cannot be past 11:59 pm')
class LessonForm(forms.ModelForm):
lesson_instrument = forms.ChoiceField(choices=instrument_list, widget=forms.Select(attrs={'class' : 'form-control', 'required' : 'True'}))
lesson_datetime_start = forms.DateTimeField(input_formats=['%Y-%m-%d %I:%M %p'], widget=forms.DateTimeInput(attrs={'class': 'form-control', 'placeholder':'YYYY-MM-DD Hour:Minute am/pm'}), validators=[validate_date1, present_date1])
lesson_datetime_end = forms.DateTimeField(input_formats=['%Y-%m-%d %I:%M %p'], required=False, widget=forms.DateTimeInput(attrs={'class': 'form-control', 'placeholder':'YYYY-MM-DD Hour:Minute am/pm'}), validators=[validate_date2, present_date2])
lesson_weekly = forms.BooleanField(required=False)
答案 0 :(得分:1)
DateTimeField
的验证者将获得datetime.datetime
对象,而不是字符串。
在这里,我们从日期时间中提取时间分量,并将其与我们恒定的最后可能时间进行比较。
import datetime
LAST_POSSIBLE_TIME = datetime.time(23, 59)
def validate_time(value):
if value.time() > LAST_POSSIBLE_TIME:
raise ValidationError('Time cannot be past 11:59 pm')
答案 1 :(得分:0)
因此,输入日期不能是过去的日期,也不能是23:59
之后的日期,因此基本上它必须在当天的其余时间之内。
怎么样:
import pytz
def date_is_not_past(dt):
if dt < datetime.now(pytz.UTC):
raise ValidationError('Date cannot be in the past')
def date_is_today(dt):
if dt.date() != datetime.now(pytz.UTC).date():
raise ValidationError('Date needs to be today')
答案 2 :(得分:0)
您想一起验证lesson_datetime_start
和lesson_datetime_end
,而不是分别验证。仅检查时间是否大于11:59 pm不会削减时间,因为即使开始时间间隔是一小时,这也会使2019-05-04 11:00 pm-2019-05-05 12:00 am无效晚上11点。
为此,请在表单中添加一个clean()
方法:
def clean(self):
cleaned_data = super().clean()
if self.cleaned_data.get('lesson_datetime_start') \
and self.cleaned_data.get('lesson_datetime_end') \
and self.cleaned_data['lesson_datetime_start'] >= self.cleaned_data['lesson_datetime_end']:
raise ValidationError({'lesson_datetime_end': "End time must be later than start time."})
return cleaned_data
以相同的方式,您可以通过减去两个datetime
字段并添加一个验证器,以确认课程的持续时间不大于某个预期的时间间隔(例如,不能超过4小时)。将它们与datetime.timedelta(hours=x)
进行比较。
您也可以在模型中进行操作,因此假设您有一个Lesson
模型,其中包含字段lesson_start
和lesson_end
:
def clean(self):
if self.lesson_start and self.lesson_end and self.lesson_start >= self.lesson_end:
raise ValidationError({'lesson_end': "End time must be later than start time."})