Первое, что вы можете сделать, это упростить тестирование для тех случаев, когда вы хотите увидеть, заполнено ли только одно из двух полей. Вы можете реализовать логический xor
следующим образом:
if bool(description2) != bool(location2):
или так:
if bool(description2) ^ bool(location2):
Я также думаю, что это было бы более понятно, если бы вы внедрили метод очистки для каждого поля отдельно, как объяснено в документах . Это гарантирует, что ошибка будет отображаться в правом поле и позволит вам просто поднять forms.ValidationError
вместо прямого доступа к объекту _errors
.
Например:
def _require_together(self, field1, field2):
a = self.cleaned_data.get(field1)
b = self.cleaned_data.get(field2)
if bool(a) ^ bool(b):
raise forms.ValidationError(u'You must specify a location and description')
return a
# use clean_description1 rather than clean_location1 since
# we want the error to be on description1
def clean_description1(self):
return _require_together('description1', 'location1')
def clean_description2(self):
return _require_together('description2', 'location2')
def clean_description3(self):
return _require_together('description3', 'location3')
def clean_description4(self):
return _require_together('description4', 'location4')
def clean_description5(self):
return _require_together('description5', 'location5')
Чтобы получить поведение, в котором требуется location1
, просто используйте required=True
для этого поля, и оно будет обработано автоматически.