How do you make django form validation dynamic?
I have a form that needs to have either a valid url or a valid file for uploading:
class ResourceUpload(ModelForm):
...
uploadedfile = forms.FileField('file')
url_address = forms.URLField('url')
...
How can I override the FileField
and URLField
validators so that Django 开发者_如何学编程only raises an error if both of the fields above are invalid but excepts one being invalid so long as the other is valid?
my solution
pros: it keeps the asterisk for the really required field and default error messages
class Form(forms.ModelForm):
field1 = SelectField
field2 = ...
field3 = ...
def __init__(self, *args, **kwargs):
super(Form, self).__init__(*args, **kwargs)
if kwargs['data']:
if kwargs['data'].get('field1') == '1':
self.fields['field2'].required = True
self.fields['field3'].required = False
elif kwargs['data'].get('field1') == '2':
self.fields['field2'].required = False
self.fields['field3'].required = True
You'll need to set them both as required=False
, so the database backend doesn't need them both filled in, and then use form cleaning:
import forms
class ResourceUpload(ModelForm):
...
uploadedfile = forms.FileField(required = False, upload_to='put/files/here')
url_address = forms.URLField(required = False)
...
def clean(self):
cleaned_data = self.cleaned_data
uploadedfile = cleaned_data.get("uploadedfile ")
url_address = cleaned_data.get("url_address ")
if not uploadedfile and not url_address :
raise forms.ValidationError("Provide a valid file or a valid URL.")
return cleaned_data
Here's my solution which really works... (tested)
def __init__(self, *args, **kwargs):
super(YourForm, self).__init__(*args, **kwargs)
if self.data and self.data.get('field_name') != 'SOMETHING':
self.fields.get('field_name2').required = True
This makes field_name2
a required field if field_name
's input was not 'SOMETHING'
.
Django rocks!
You should take a look at this package django-extra-field-validation
from django.db import models
from extra_validator import FieldValidationMixin
class MyModel(FieldValidationMixin, models.Model):
uploadedfile = models.FileField(upload_to='upload/path', blank=True, default='')
url_address = models.URLField(blank=True, default='')
REQUIRED_TOGGLE_FIELDS = ['uploadedfile', 'url_address']
This will validate that only one of the fields can be provided raising validation error if both are used.
精彩评论