The problem
Add custom validation to a form field in Django 1.3, the form is created by the generic view CreateView.
The model
class Picture(models.Model):
file = models.ImageField(upload_to=get_image_path)
filename = models.CharField(max_length=50, blank=True)
user = models.ForeignKey(User, editable=False)
upload_date = models.DateTimeField(auto_now_add=True,editable=False)
Generic view CreateView, a bit modified
class PictureCreateView(CreateView):
model = Picture
def clean_file(self,form):
if image:
if image._size > settings.MAX_IMAGE_SIZE:
raise ValidationError("Image file too large ( > 20mb )")
else:
raise ValidationError("Couldn't read uploaded image")
def get_form(self, form_class):
form = super(PictureCreateView, self).get_form(form_class)
form.instance.user = self.request.user
return form
def form_invalid(self, form):
...omitted none important code...
response = JSONResponse(data, {}, response_mimetype(self.request))
response['Content-Disposition'] = 'inline; filename=files.json'
return response
# Called when we're sure all fields in the form are valid
def form_valid(self, form):
...omitted none important code...
response = JSONResponse(data, {}, response_mimetype(self.request))
response['Content-Disposition'] = 'inline; filename=files.json'
return response
My question is: How can I do custom validation on the file field, before form_valid() is reached?
In short, what I’ve done so far
According to the documentation here – https://docs.djangoproject.com/en/dev/ref/forms/validation/
I should be able to override the file fields form validator, which I’m trying to do with clean_file()
“The clean_() method in a form subclass – where is replaced with the name of the form field attribute. ”
This would have been easy if I had created the form manually, but it’s created by Django from the model by the generic view.
My current solution, which is a ugly hack:
You can see that I’ve overridden form_valid() and form_invalid(), in form_valid() I now call clean_file()
and if it’s a error I call form_invalid(). This creates a few problems, for example I need to create the error message response manually.
Why not create your modelform ?
Then you could use it in your view with the form_class attribute: