2014-12-18 2 views
2

У меня есть вид, где я проверяю дату и время отправки формы, проверяя, что дата + время не прошло. Дата и время - это два отдельных поля. Он работает, но я знаю, что его неправильный способ сделать это, а дата + время должно быть подтверждено в Django Forms.Django Validate Date & Time in 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: 
    ... 

теперь моя цель состоит в том, чтобы иметь что-то вроде выше в 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', ...] 

Редакция:

рабочий код:

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 

Спасибо всем за помощь, особенно xyres за его работу и за то, что пациент со мной!

+0

Там нет фактически никакой необходимости определить '__init__' метод в ваших формах. Но где проблема? – xyres

+0

Его «KeyError». он жалуется на 'my_time = self.cleaned_data ['my_time']' – WayBehind

+0

Попробуйте использовать 'my_time = self.cleaned_data.get ('my_time')'. – xyres

ответ

1

Я попытаюсь ответить в последний раз. Вместо того чтобы делать def clean_my_date(...), сделайте следующее:

def clean_my_time(self): 
    # rest of your code remains same 

Если вышеуказанное решение не работает, try this answer.

Update

Поскольку выше код работал, я чувствую, что я должен попытаться объяснить, как и почему.

Давайте посмотрим на порядок полей в форму

fields = ['my_date', 'my_time', ...] 

Как вы можете видеть my_time поле приходит послеmy_date поле. Таким образом, когда ваш код был как

def clean_my_date(self) 

clean() метод вашей формы вызывается и возвращает объект словаря под названием cleaned_data. У этого cleaned_data dict есть все ключи i.e. поля вашей формы доmy_date раздел. Любое поле, которое после my_date не будет находиться в cleaned_data. Как, my_time поле после my_date поле, оно не было в cleaned_data. Вот почему вы получили KeyError.

После изменения кода

def clean_my_time(self) 

метод clean() вернулся cleaned_data со всеми полями ДОmy_time. Поскольку my_date подходит к my_time, поэтому он присутствует в cleaned_data. Следовательно, нет ошибки.

Так что это зависит от порядка ваших полей формы. Если вы хотите проверить два поля вместе, сделайте это в методе clean_my_field(self) этого поля, которое поступит позже по порядку. Ответ отправлен Jérôme Thiard также является хорошей альтернативой.

+1

Еще раз спасибо за вашу помощь и ваше терпение! С небольшой настройкой я смог ее решить. Рабочий код в моем OP. Еще раз спасибо! – WayBehind

+0

@WayBehind Я рад, что смог помочь. :) – xyres

+1

@WayBehind В случае повторного использования той же проблемы я обновил свой ответ с некоторым объяснением. – xyres

2

Вы пытаетесь проверить несколько полей. Эта точка хорошо освещена документацией django, см. https://docs.djangoproject.com/en/1.7/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other.

Задача должна быть выполнена в методе clean. Предполагая Джанго 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', ...] 
+0

Спасибо за отзыв. Он возвратил ту же ошибку, что и мой OP. Я думаю, что с небольшой настройкой ваш код тоже будет работать! – WayBehind