Django 验证表单中的日期和时间

Way*_*ind 5 python forms django validation

我有一个视图,我在表单提交时验证日期和时间,确保日期 + 时间没有过去。日期和时间是两个独立的字段。它有效,但我知道它的错误方式,并且应该在 Django Forms 中验证日期+时间。

这是在我的 view.py

(可能没有以正确的方式完成,但它有效)

my_date = request.session['reservationdate'] #in "mm/dd/yyyy" format
my_time = request.session['reservationtime'] #in "hh:mm" format
my_date_time = (my_date + ' ' + my_time + ':00') #convert to "mm/dd/yyyy hh:mm:ss"
my_date_time = datetime.strptime(my_date_time, '%m/%d/%Y %H:%M:%S') #convert to valid datetime
if datetime.now() <= my_date_time:
    #do this
else:
     ...
Run Code Online (Sandbox Code Playgroud)

现在我的目标是在 Django 表单中有类似上面的内容:

class MyForm(forms.ModelForm):  

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)

        self.fields['my_date'].required = True
        self.fields['my_time'].required = True
        ...

    def clean_my_date(self):
        my_date = self.cleaned_data['my_date']
        my_time = self.cleaned_data['my_time']
        my_date_time = (my_date + ' ' + my_time + ':00')
        my_date_time = datetime.strptime(my_date_time, '%m/%d/%Y %H:%M:%S')
        if datetime.now() <= my_date_time:
            raise forms.ValidationError(u'Wrong Date!')
        return my_date

    class Meta:
        model = MyModel
        fields = ['my_date', 'my_time', ...]
Run Code Online (Sandbox Code Playgroud)

编辑:

工作代码:

def clean_my_time(self):
   my_date = self.cleaned_data['my_date']
   my_time = self.cleaned_data['my_time']
   my_date_time = ('%s %s' % (my_date, my_time))
   my_date_time = datetime.strptime(my_date_time, '%Y-%m-%d %H:%M:%S')
   if datetime.now() >= my_date_time:
        raise forms.ValidationError(u'Wrong Date or Time! "%s"' % my_date_time)
   return my_time
Run Code Online (Sandbox Code Playgroud)

感谢所有人的帮助,尤其是xyres对他的工作和对我的耐心!

小智 6

您正在尝试验证多个字段。django 文档很好地涵盖了这一点,请参阅https://docs.djangoproject.com/en/1.7/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

这项工作必须在clean方法中完成。假设 django 1.7,你的代码可能看起来像

class MyForm(forms.ModelForm):  

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)

        self.fields['my_date'].required = True
        self.fields['my_time'].required = True
        ...

    def clean(self):
        cleaned_data = super(MyForm, self).clean()
        # here all fields have been validated individually,
        # and so cleaned_data is fully populated
        my_date = cleaned_data.get('my_date')
        my_time = cleaned_data.get('my_time')
        if my_date and my_time:
            my_date_time = (my_date + ' ' + my_time + ':00')
            my_date_time = datetime.strptime(my_date_time, '%m/%d/%Y %H:%M:%S')
            if datetime.now() <= my_date_time:
                msg = u"Wrong Date time !"
                self.add_error('my_date', msg)
                self.add_error('my_time', msg)
        return cleaned_data

    class Meta:
        model = MyModel
        fields = ['my_date', 'my_time', ...]
Run Code Online (Sandbox Code Playgroud)


xyr*_*res 4

我会尝试最后一次回答。不要这样做def clean_my_date(...),而是这样做:

\n\n
def clean_my_time(self):\n    # rest of your code remains same\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果上述解决方案不起作用,请尝试此答案

\n\n

更新

\n\n

由于上面的代码有效,我觉得我应该尝试解释原因和方法。

\n\n

让我们看看表单中字段的顺序

\n\n
fields = [\'my_date\', \'my_time\', ...]\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如,您可以看到一个my_time一个字段。所以,当你的代码就像 my_date

\n\n
def clean_my_date(self) \n
Run Code Online (Sandbox Code Playgroud)\n\n

clean()调用表单的方法并返回一个名为 的字典对象cleaned_data。该字典包含表单中最多cleaned_data字段的所有键(即字段) 。之后的任何字段都不会出现在. 因为,字段是一个又一个字段,所以它不在 中。这就是为什么你有一个. my_datemy_datecleaned_datamy_timemy_datecleaned_dataKeyError

\n\n

将代码更改为之后

\n\n
def clean_my_time(self) \n
Run Code Online (Sandbox Code Playgroud)\n\n

clean()方法返回cleaned_data所有字段upto my_time。如前所述,因此它出现在my_date中。因此,没有错误。my_timecleaned_data

\n\n

所以这取决于表单字段的顺序。如果您想同时验证两个字段,请在clean_my_field(self)按顺序出现的字段的方法中执行此操作。J\xc3\xa9r\xc3\xb4me Thiard发布的答案也是一个不错的选择。

\n