2

From everything I can find, the FileField.clean() method should be executed when a file is added to a model, but the method is simply never executed.

Note that I'm referring to the models.FileField object, not forms.FileField. See: related stackoverflow question

I am looking to validate that a file saved in models.FileField is of a certain file type and below a specified size. This is using the Django Rest Framework. The clean() method is never called on save. Why not?

View:

class FileUploadCreate(generics.CreateAPIView):

    serializer_class = FileUploadSerializer

    def get_queryset(self):
        return FileUpload.objects.filter()

    def perform_create(self, serializer):

        upload = self.request.data['file']

        instance = serializer.save(
           name='Name',
           datafile=upload,
        )

        instance.save()            

Model:

class ContentTypeRestrictedFileField(models.FileField):

    def __init__(self, *args, **kwargs):
        # Log that it hits here
        super(ContentTypeRestrictedFileField, self).__init__(*args, **kwargs)

    def clean(self, *args, **kwargs):
        print("I NEVER MAKE IT HERE")
        data = super(ContentTypeRestrictedFileField, self).clean(*args, **kwargs)
        file = data.file
        try:
            content_type = file.content_type
            if content_type in self.content_types:
                if file._size > self.max_upload_size:
                    raise ValidationError('Too big')
            else:
                raise ValidationError('Filetype not supported.')
        except AttributeError:
            pass

        return data


class FileUpload(BaseModel):
    name = models.CharField(max_length=128, blank=True, null=True)
    datafile = ContentTypeRestrictedFileField(content_types=['video/x-msvideo', 'application/pdf', 'video/mp4', 'audio/mpeg', ], max_upload_size=1024)
Community
  • 1
  • 1
Josh
  • 21
  • 2
  • what exactly you need from that process? such as; rename file, make a validator, or what? – binpy Mar 01 '17 at 15:16
  • I'm looking to validate and restrict of file content type and file size. This is via the django-rest-framework, so there are no formfields. – Josh Mar 01 '17 at 15:21
  • are you following this answer? http://stackoverflow.com/a/9016664/6396981 – binpy Mar 01 '17 at 15:32
  • 1
    What exactly is your question? What do you mean by "when a file is added to a model"? That's ambiguous. Please add a [mcve] – Håken Lid Mar 01 '17 at 15:37
  • @SancaKembang Yes, that is what I've implemented, but clean() is never executed. – Josh Mar 01 '17 at 16:08
  • 1
    Try adding the line `instance.full_clean()` before `instance.save()`. – Håken Lid Mar 01 '17 at 16:15
  • If your code still doesn't work well, I suggest you to handle it using validator inside `serializers.ModelSerializer`, see this [docs](http://www.django-rest-framework.org/api-guide/validators/#limitations-of-validators), this answer is an example to do it http://stackoverflow.com/a/31278625/6396981 – binpy Mar 01 '17 at 16:25

1 Answers1

0

is_valid() method automatically executes clean() and does validation in django.

For instance

form = some_form(request.POST)
if form.is_valid():
    # clean() is automatically executed