开发者

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():
...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜