I've been trying to implement a file size validator in django on a filefield, but I can't really make it work.
Everything works right until I add this validator. After I add it, I can't upload files anymore at all. The error says "File field does not have a full_clean attribute".
views.py
from django.shortcuts import render, get_object_or_404 from .models import Oferta, CV from django.contrib import messages from django.core.paginator import Paginator def incarcarecv(req): context = { 'title': "Incarcare CV | Best DAVNIC73" } if req.method == 'POST': nume = req.POST['nume'] prenume = req.POST['prenume'] telefon = req.POST['telefon'] email = req.POST['email'] cv = req.FILES['CV'] if(req.user.is_authenticated): cv_upload = CV( solicitant=req.user, nume=nume, prenume=prenume, telefon=telefon, emailContact=email ) cv_upload.CVFile.full_clean() cv_upload.CVFile.save(cv.name, cv) cv_upload.save() req.user.profile.cvuri.append(cv_upload.id) req.user.profile.save() messages.success(req, 'CV depus cu succes!') else: messages.error(req, 'Trebuie sa fii logat pentru a depune CV-ul!') return render(req, "../templates/pagini/incarcare-cv.html", context) models.py
from django.db import models from django.contrib.auth.models import User from .validators import validate_file_size # Create your models here. class Oferta(models.Model): solicitant = models.ForeignKey(User, on_delete=models.CASCADE) dataSolicitare = models.DateField(auto_now_add=True) cor = models.CharField(max_length=25) denumireMeserie = models.CharField(max_length=12) locuri = models.IntegerField() agentEconomic = models.CharField(max_length=50) adresa = models.CharField(max_length=150) dataExpirare = models.DateField() experientaSolicitata = models.CharField(max_length=200) studiiSolicitate = models.CharField(max_length=200) judet = models.CharField(max_length=20) localitate = models.CharField(max_length=25) telefon = models.CharField(max_length=12) emailContact = models.EmailField(max_length=40) rezolvata = models.BooleanField(default=False) def __str__(self): return self.cor class CV(models.Model): solicitant = models.ForeignKey(User, on_delete=models.CASCADE) dataUploadCV = models.DateField(auto_now_add=True) nume = models.CharField(max_length=12) prenume = models.CharField(max_length=12) telefon = models.CharField(max_length=12) emailContact = models.EmailField(max_length=40) CVFile = models.FileField(upload_to='documents/%d/%m/%Y', validators=[validate_file_size]) rezolvata = models.BooleanField(default=False) def __str__(self): return self.nume + " " + self.prenume + ": " + str(self.CVFile) validators.py
from django.core.exceptions import ValidationError def validate_file_size(value): filesize=value.size if filesize > 5000000: raise ValidationError("Maximum 5MB!") I just can't seem to get why. Can you help me fix my code? As far as I know, .full_clean() runs some default django validators + the ones set in the model.
But actually it does not work.
Exception Value: 'FieldFile' object has no attribute 'full_clean' Can you explain to me why is this happening and how can I make my validator run?
Thanks.
//by the way, someone recommended to change the order of the lines like this -
cv_upload.CVFile.save(cv.name, cv) cv_upload.CVFile.full_clean() but it does not work anyway.
01 Answer
As the error says, full_clean() isn't a method of a model field. It's a method of the model itself.
cv_upload.full_clean() works.
But you should just initialise your cv_upload with the file directly:
cv_upload = CV( solicitant=..., ..., CVFile=cv) then you don't have to save the file separately, see the docs.
Also, you're running full_clean() but not catching any exceptions. What happens if validation fails? A ValidationError will be thrown. If you don't catch it, your view will return a HTTP 500 error (it will just crash).
So wrap it in a try ... except clause:
try: cv_upload.full_clean() except ValidationError as e: messages.error(request, e) else: cv_upload.save() messages.success(request, "yeah!") 2