Opened 3 years ago
Closed 3 years ago
#32852 closed Bug (invalid)
Attribute error for missing content_type on File object for modeladmin change request
Reported by: | Aiven Timptner | Owned by: | nobody |
---|---|---|---|
Component: | File uploads/storage | Version: | 3.2 |
Severity: | Normal | Keywords: | content_type |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I've got a model with a FileField and the corresponding admin page created with modeladmin. To validate the file type and only allow PDFs I wrote a custom validator which checks the content_type attribute on user (staff) uploads. When objects are created or the file itself get changed everything works as expected. But if I change some others fields on the model I receive an AttributeError.
def validate_file_extension(value: File): """Check if uploaded file content is pdf""" if value.file.content_type != 'application/pdf': raise ValidationError("Only PDF are allowed") def user_directory_path(instance: File, filename: str) -> str: """Return a unix-like storage path as string with random file name""" filename = token_urlsafe(5) + '.pdf' filepath = f"jobs/{filename}" if Job.objects.filter(file=filepath).exists(): return user_directory_path(instance, filename) return filepath class Job(models.Model): title = models.CharField(max_length=250) description = models.TextField() file = models.FileField(upload_to=user_directory_path, validators=[validate_file_extension], blank=True, null=True) expired_on = models.DateTimeField(blank=True, null=True) created_on = models.DateTimeField(auto_now_add=True) updated_on = models.DateTimeField(auto_now=True)
For now I solved it by ignoring AttributeErrors on validation
class Job(models.Model): title = models.CharField(max_length=250) description = models.TextField() file = models.FileField(upload_to=user_directory_path, validators=[validate_file_extension], blank=True, null=True) expired_on = models.DateTimeField(blank=True, null=True) created_on = models.DateTimeField(auto_now_add=True) updated_on = models.DateTimeField(auto_now=True) def clean_fields(self, exclude=None): try: super().clean_fields(exclude=exclude) except AttributeError: # Handle missing content_type on file object pass
Change History (5)
comment:1 by , 3 years ago
Cc: | added |
---|
comment:2 by , 3 years ago
Cc: | removed |
---|
comment:3 by , 3 years ago
comment:4 by , 3 years ago
Replying to Aiven Timptner:
I've got a model with a FileField and the corresponding admin page created with modeladmin. To validate the file type and only allow PDFs I wrote a custom validator which checks the content_type attribute on user (staff) uploads. When objects are created or the file itself get changed everything works as expected. But if I change some others fields on the model I receive an AttributeError.
Yes, all of your validators will be called when you save a model. And your a assuming that your file has a content_type
attribute, but only the file sent to a request has a content type(the TemporaryUploadedFile), when you change your model and keep your current file, all of your validators will receive a File and not TemporaryUploadedFile, and the File object does not have a content type.
You can assume that all pdf files follow the pattern *.pdf
and check if the filename ends with the pattern and/or check the types of File, something like:
def validate_file_extension(value: File): """Check if uploaded file content is pdf""" if not value.file.name.endswith(".pdf"): raise ValidationError("Only PDF are allowed")
comment:5 by , 3 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
This looks like a support issue. Please see TicketClosingReasons/UseSupportChannels for appropriate locations.
What's the traceback? Can you explain why Django is at fault?