Django modelform remove "required" attribute based on other field choice
I have ModelForm with several fields. Some of fields are required, some not. Also I have Select field with different choices, and I want to make some of fields "required" or not based on this Select field choice.
I tried in clean() method of Form
def clean(self):
cleaned_data = self.cleaned_data
some_field = cleaned_data.get("some_field")
if some_field == 'some_value':
self.fields['开发者_JAVA技巧other_field'].required = False
return cleaned_data
but it doesn't work
See the Django documentation on Cleaning and validating fields that depend on each other. The standard practice would be to perform the following handling instead:
def clean(self):
cleaned_data = self.cleaned_data
some_field = cleaned_data.get("some_field")
if some_field == 'some_value':
# 'other_field' is conditionally required.
if not cleaned_data['other_field']:
raise forms.ValidationError("'Other_field' is required.")
return cleaned_data
You have the right idea but the problem is that the individual field validations have already run before the form clean. You have a couple options. You could make the field not required and handle the logic of when it is required in your form.clean. Or you could leave the field as required and remove the validation errors it might raise in the clean.
def clean(self):
cleaned_data = self.cleaned_data
some_field = cleaned_data.get("some_field")
if some_field == 'some_value':
if 'other_field' in self.errors:
del self.errors['other_field']
cleaned_data['other_field'] = None
return cleaned_data
This has some problems in that it removes all errors, not just missing/required errors. There is also a problem with the cleaned_data. You now have a required field which isn't in the cleaned_data which is why I've added it as None. The rest of your application will have to handle this case. It might seem odd to have a required field which doesn't have a value.
If you like to print error message for required field in common way, you can do this:
def clean(self):
cleaned_data = super(PasswordChangeForm, self).clean()
token = cleaned_data.get('token')
old_password = cleaned_data.get('old_password')
if not token and not old_password:
self._errors['old_password'] = self.error_class([self.fields['old_password'].error_messages['required']])
I found a possible solution. You can use your condition before form.is_valid() and include your change in your field.
if form.data['tid_id'] is None: # my condition
form.fields['prs_razonsocial'].required = True
form.fields['prs_nombres'].required = False
form.fields['prs_apellidos'].required = False
if form.is_valid():
...
加载中,请稍侯......
精彩评论