Opened 5 months ago

Last modified 6 weeks ago

#28428 new New feature

Add support for Pathlib objects in django.core.storage

Reported by: Tom Forbes Owned by: nobody
Component: File uploads/storage Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Someday/Maybe
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Code in django.core.storage will explode when given a Pathlib object on Python 3.4 and 3.5. For example, this throws a cryptic AttributeError: 'PosixPath' object has no attribute 'rfind' exception due to generate_filename only expecting strings:

def upload_to(filename):
      return pathlib.Path(filename)

class Storage(models.Model):
   file = models.FileField(upload_to=upload_to)

More generally, it would be nice if all methods in the django.core.files accepted pathlib objects, and used pathlib objects internally. For compatibility reasons I think strings would have to be returned.

Change History (4)

comment:1 Changed 5 months ago by Tim Graham

Component: UncategorizedFile uploads/storage

Do you have a use case in mind? What are the advantages?

comment:2 Changed 5 months ago by Tom Forbes

In my case we have a bunch of methods in our applications that all use pathlib instances, some of which is used by our upload_to methods. It feels a bit strange to have to return the string representation from them when interacting with Django. With Python 2 support out of the picture there isn't much reason to, other than historical ones.

The main advantage is readability, in a lot of cases using Pathlib makes os.path heavy code a lot less dense.

comment:3 Changed 5 months ago by Tim Graham

Triage Stage: UnreviewedSomeday/Maybe

I'm not sure. I guess I'd have to see a patch to evaluate the idea.

comment:4 Changed 6 weeks ago by Roger G. Coram

As of Python 3.6 (specifically running 3.6.3) django.core.files.storage.Storage.generate_filename doesn't appear to raise this error when passed a pathlib.Path. Instead the os.path.split therein appears to handle it as expected:

Python 3.6.3 (default, Oct  6 2017, 08:44:35) 
>>> import os, pathlib
>>> os.path.split(pathlib.PosixPath("some/folder/test_with_space.txt"))
('some/folder', 'test_with_space.txt')
Note: See TracTickets for help on using tickets.
Back to Top