Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you make django form validation dynamic?

Tags:

forms

django

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?

like image 315
sithbunny Avatar asked Dec 01 '22 10:12

sithbunny


2 Answers

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
like image 127
VoSi Avatar answered Dec 04 '22 03:12

VoSi


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          
like image 31
Dominic Rodger Avatar answered Dec 04 '22 03:12

Dominic Rodger