Code

Opened 3 years ago

Closed 3 years ago

#16396 closed Bug (invalid)

Validation Problem Reading Files When Using Custom Storage Module

Reported by: dadealeus@… Owned by: nobody
Component: Documentation Version: 1.3
Severity: Normal Keywords: validation storage custom
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Using a custom storage module I wrote using the Rackspace CloudFiles API, if I perform any sort of reads on a file object during custom validation of uploaded files, I need to seek back the beginning of the file before I return it as cleaned_data.

Example form class:

class UploadImageForm(forms.Form):
        """ Form to handle design uploads """
        design = forms.ImageField(error_messages={'required' : "Please select an image to upload."})
        
        def clean_design(self):
            
            from generic.media import utils
            
            # Verify uploaded image is an image
            data = self.cleaned_data['design']
            
            # Open the image so we can autocrop before checking dimensions
            image = PIL.open(StringIO(data.read()))
    
            # Autocrop the image and then check the dimensions
            image = utils.autoCrop(image)
            
            # Minimum image size
            min_image_size = 90
            
            # Verify the image size
            width, height = image.size
            width = float(width)
            height = float(height)
            ratio = height / width
            
            # Perform various validation checks... Example:
            if (ratio > 16) or (ratio < 0.0625):
                raise forms.ValidationError("The uploaded image's aspect ratio is too extreme. Please use an image that looks more square.")
    
            return data

Upon trying to save an image with the cleaned data (while using my custom storage module) via a custom view, the file object has no data associated with it unless I seek back to 0 before returning the cleaned data.

Please note that this only occurs when using my custom storage module and when performing custom validation on the uplodaded data. Using the native django storage, the exact same code functions without any issues.

I would like to see a note added to the custom storage documentation that specifies something like:

"If performing custom validation on a file object while using a custom storage module, be sure to seek back to zero before passing back the cleaned data as the file object is returned in its current state.

Example:

class UploadImageForm(forms.Form):
        """ Form to handle image uploads """
        image = forms.ImageField(error_messages={'required' : "Please select an image to upload."})
        
        def clean_image(self):
            
            data = self.cleaned_data['image']
            stringIO = data.read()
            
            # Perform some custom validation

            # Reset the file object before returning it as cleaned data
            data.seek(0)
            return data

"

Attachments (0)

Change History (1)

comment:1 Changed 3 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

Given the following sentence, I'd say the bug is in your custom storage module:

Using the native django storage, the exact same code functions without any issues.


It's up to the storage model to reset the file, not the form. For instance, django.core.files.base.File does it in open and __iter__ (via chunks).

The docs say it's possible to override any of the storage methods explained in File storage API, but don't say how. They assume you will read the source and understand the requirements. If you don't use the File class or a subclass, you should make sure that your code has a similar behavior.

Given that we hardly have the most basic documentation here, I don't think it makes sense to describe this specific pitfall.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.