18

After deploying on a server on digital ocean using nginx, gunicorn, django, and virtualenv, I try to use collectstatic:

python manage.py collectstatic --settings=config.settings.production

As you can see I have multiple setting files. One base, one local and one production setting file. Below is the error:

    Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/home/tony/vp/vpenv/lib/python3.5/site-packages/django/core/management/__init__.py", line 363, in execute_from_command_line
    utility.execute()
  File "/home/tony/vp/vpenv/lib/python3.5/site-packages/django/core/management/__init__.py", line 355, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/tony/vp/vpenv/lib/python3.5/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/tony/vp/vpenv/lib/python3.5/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/home/tony/vp/vpenv/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 173, in handle
    if self.is_local_storage() and self.storage.location:
  File "/home/tony/vp/vpenv/lib/python3.5/site-packages/django/utils/functional.py", line 239, in inner
    return func(self._wrapped, *args)
  File "/home/tony/vp/vpenv/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/tony/vp/vpenv/lib/python3.5/site-packages/django/core/files/storage.py", line 283, in location
    return abspathu(self.base_location)
  File "/home/tony/vp/vpenv/lib/python3.5/posixpath.py", line 357, in abspath
    if not isabs(path):
  File "/home/tony/vp/vpenv/lib/python3.5/posixpath.py", line 64, in isabs
    return s.startswith(sep)
AttributeError: 'PosixPath' object has no attribute 'startswith'

my production.py settings file contains the following:

MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = 'media/'
STATIC_ROOT = BASE_DIR / 'static'

my base dir is as follows (imported from the base setting file):

BASE_DIR = Path(__file__).resolve().parent.parent.parent

What could be the cause?

Andrea Corbellini
  • 17,339
  • 3
  • 53
  • 69
Tony
  • 2,382
  • 7
  • 32
  • 51

3 Answers3

14

You're using Python 3.5. Support for Path objects in the os module was added in Python 3.6. You can:

  • either upgrade to Python 3.6; or

  • avoid using Path objects:

    BASE_DIR = os.path.abspath(os.path.join(__file__, '../../../'))
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    STATIC_ROOT = os.path.join(BASE_DIR, 'static')
    
Andrea Corbellini
  • 17,339
  • 3
  • 53
  • 69
  • 1
    You are right! I would like to upgrade to the newer version but running pip install --upgrade python wont do the work. I think I need to re create the virtualenv – Tony Jan 10 '18 at 20:52
  • Thanks, I have python 3.9 but had this issue, but followed your answer and it's solved now! – a3k Jan 13 '21 at 07:17
10

This was my earlier settings . I am using Python 3.5. Django 2.1.

BASE_DIR = Path(__file__).resolve().parent.parent.parent
STATIC_ROOT = BASE_DIR / 'static'

I changed just one thing:

STATIC_ROOT = str(BASE_DIR / 'static')

It worked fine.

Arindam Roychowdhury
  • 5,927
  • 5
  • 55
  • 63
1

In my case it was because i installed in manually (which was the old version). the new python versions (>=3.6) have the pathlib library included.

So I simply did pip uninstall pathlib so that it could use the one that comes already bundled with python. When i ran the code again it worked fine.

Hissaan Ali
  • 2,229
  • 4
  • 25
  • 51