Opened 8 years ago

Closed 7 years ago

Last modified 4 years ago

#4345 closed (fixed)

FileField cannot be used with unique=True

Reported by: Fabian Fagerholm <fabbe@…> Owned by: Gulopine
Component: Database layer (models, ORM) Version: master
Severity: Keywords: fs-rf-fixed
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

The following model will result in an error in the (current) admin:

class Foo(Model):
    name = CharField(maxlength=50)
    file = FileField(upload_to="upload", unique=True)

When trying to add a Foo object in the admin, the following error occurs:

ProgrammingError at /admin/browser/documentfile/add/
can't adapt
Request Method: 	POST
Request URL: 	http://localhost:8000/admin/browser/documentfile/add/
Exception Type: 	ProgrammingError
Exception Value: 	can't adapt
Exception Location: 	/django_src/django/db/backends/util.py in execute, line 12

Removing unique=True from the file field makes it work -- but what will happen if a file with the same name is uploaded twice, attached to different objects? What will happen when either one is removed?

Change History (10)

comment:1 Changed 8 years ago by Fabian Fagerholm <fabbe@…>

  • Component changed from Database wrapper to Documentation
  • Needs documentation unset
  • Needs tests unset
  • Owner changed from adrian to jacob
  • Patch needs improvement unset

Hmm...

Apparently, what happens is this:
If the file already exists, the new file will be named <base name><_>.<suffix>, where <_> is the number of underscores needed to make the name unique. So, for example, when a file named foo.png is uploaded multiple times, the second file will be named foo_.png, the third will be foo__.png and so on.

This should probably be documented, though. I'm not sure whether this renaming happens in the admin code or in the model code.

comment:2 Changed 8 years ago by SmileyChris

  • Triage Stage changed from Unreviewed to Accepted

Well it shouldn't be erroring, so let's accept this as a valid bug.

Perhaps FileField just shouldn't accept the unique=True argument.

comment:3 Changed 8 years ago by Fabian Fagerholm <fabbe@…>

Just as a side note: http://www.djangoproject.com/documentation/db-api/ actually documents this:

save_FOO_file(filename, raw_contents)

"For every FileField, the object will have a save_FOO_file() method, where FOO is the name of the field. This saves the given file to the filesystem, using the given filename. If a file with the given filename already exists, Django adds an underscore to the end of the filename (but before the extension) until the filename is available."

Could be mentioned in the FileField docs as well, though.

comment:4 Changed 8 years ago by jacob

  • Component changed from Documentation to Database wrapper
  • Owner changed from jacob to adrian

This isn't a doc bug; it's a model API bug. Actually, though, I'm not clear on what a "unique" file would be -- do we have do examine each uploaded file against all the others? That's crazy talk, I think... Perhaps just disallowing unique on FileFields would do the trick.

comment:5 Changed 8 years ago by Gulopine

  • Keywords fs-rf added

comment:6 Changed 8 years ago by Gulopine

  • Keywords fs-rf-fixed added; fs-rf removed

comment:7 Changed 7 years ago by Gulopine

  • milestone set to 1.0 beta

comment:8 Changed 7 years ago by Gulopine

  • Owner changed from nobody to Gulopine
  • Status changed from new to assigned

comment:9 Changed 7 years ago by jacob

  • Resolution set to fixed
  • Status changed from assigned to closed

(In [8244]) File storage refactoring, adding far more flexibility to Django's file handling. The new files.txt document has details of the new features.

This is a backwards-incompatible change; consult BackwardsIncompatibleChanges for details.

Fixes #3567, #3621, #4345, #5361, #5655, #7415.

Many thanks to Marty Alchin who did the vast majority of this work.

comment:11 Changed 4 years ago by jacob

  • milestone 1.0 beta deleted

Milestone 1.0 beta deleted

Note: See TracTickets for help on using tickets.
Back to Top