Какие данные Django 1.5 SplitDateTimeWidget отправляет в form.clean()?
У меня есть следующая форма:
class TripForm(IntranetForm):
def __init__(self, *args, **kwargs):
super(TripForm, self).__init__(*args, **kwargs)
self.helper.layout = Layout(
Field('reason', css_class='input-xlarge'),
Field('departure_date'),
Field('return_date'),
Field(
'date_and_time_of_first_appointment',
),
Field(
'date_and_time_final_appointment_finishes',
),
Field(
'departure_location',
template='travel/related_departure.html',
),
Field(
'destination',
template='travel/related_destination.html',
),
Field('mode_of_transport', css_class='input-xlarge'),
Field('seating_preference', css_class='input-xlarge'),
Field('special_requests', css_class='input-xlarge'),
FormActions(
Submit(
'save_changes',
'Save changes',
css_class = "btn-primary",
),
Button(
'cancel',
'Cancel',
onclick = 'history.go(-1);'
),
),
)
def clean(self):
cleaned_data = super(TripForm, self).clean()
departure_date = cleaned_data.get("departure_date")
return_date = cleaned_data.get("return_date")
a1 = cleaned_data.get("date_and_time_of_first_appointment")
af = cleaned_data.get("date_and_time_final_appointment_finishes")
if departure_date < datetime.date.today():
msg = u"Must be a date in the future."
self._errors["departure_date"] = self.error_class([msg])
del cleaned_data["departure_date"]
if a1.date() < departure_date:
msg = u"Must be after the departure date."
self._errors["date_and_time_of_first_appointment"] = self.error_class([msg])
del cleaned_data["date_and_time_of_first_appointment"]
if return_date < departure_date:
msg = u"Must be after the departure date."
self._errors["return_date"] = self.error_class([msg])
del cleaned_data["return_date"]
if af < a1 or af.date() > return_date:
msg = u"Must be after the first appointment and before the return date."
self._errors["date_and_time_final_appointment_finishes"] = self.error_class([msg])
del cleaned_data["date_and_time_final_appointment_finishes"]
return cleaned_data
class Meta:
model = Trip
fields = (
'reason',
'departure_date',
'return_date',
'date_and_time_of_first_appointment',
'date_and_time_final_appointment_finishes',
'departure_location',
'destination',
'mode_of_transport',
'seating_preference',
'special_requests',
)
widgets = {
'date_and_time_of_first_appointment': SplitDateTimeWidget(),
'date_and_time_final_appointment_finishes': SplitDateTimeWidget(),
}
Тесты, аналогичные приведенным ниже, работают нормально, когда я не использую SplitDateTimeWidget
,
def test_trip_form_with_good_data(self):
form_data = {
'reason': 'HE',
'departure_date': timezone.datetime.today(),
'return_date': timezone.datetime.today(),
'date_and_time_of_first_appointment': timezone.now(),
'date_and_time_final_appointment_finishes': timezone.now(),
'departure_location': 1,
'destination': 1,
'mode_of_transport': 'TR',
'seating_preference': 'Near the front',
'special_requests': 'Make it nice',
}
form = TripForm(data=form_data)
self.assertTrue(form.is_valid())
Но тесты больше не запускаются, когда SplitDateTimeWidget
используется для DateTime
поля. Они выдают ошибки, а не сбои, а именно:
AttributeError: 'NoneType' object has no attribute 'date'
всякий раз, когда a1
переменная доступна в моей переопределенной форме clean
метод.
Я посмотрел на соответствующий исходный код и не мог понять, почему с помощью SelectDateTimeWidget
потребовал бы другого ввода в командной строке или в тестах, но это явно так. Как мои тесты должны предоставлять данные таким образом, чтобы форма clean
метод сможет получить доступ?
РЕДАКТИРОВАТЬ: принимая мои реплики из рендеринга HTML, я также пытался получить отдельные даты и время из таких полей, как date_and_time_of_first_appointment_0
а также date_and_time_of_first_appointment_1
и объединяя их перед сравнением в clean
метод, но безрезультатно.
1 ответ
Я решил это. Рендеринг HTML действительно говорил мне, что делать, но я поставил свое решение не в том месте.
Вместо того, чтобы искать отдельные поля в чистом методе, что я и пытался изначально, вам нужно поместить их в свои тестовые данные. Django объединит их к моменту передачи данных clean()
, Мои тесты теперь выглядят примерно так:
def test_trip_form_with_good_data(self):
form_data = {
'reason': 'HE',
'departure_date': timezone.datetime.today(),
'return_date': timezone.datetime.today(),
'date_and_time_of_first_appointment_0': timezone.now().date(),
'date_and_time_of_first_appointment_1': timezone.now().time(),
'date_and_time_final_appointment_finishes_0': timezone.now().date(),
'date_and_time_final_appointment_finishes_1': timezone.now().time(),
'departure_location': 1,
'destination': 1,
'mode_of_transport': 'TR',
'seating_preference': 'Near the front',
'special_requests': 'Make it nice',
}
form = TripForm(data=form_data)
self.assertTrue(form.is_valid())
И все снова проходит.