django Pycharm 2020.2.2 not resolving static files when using "pathlib.Path" to address BASE_DIR

Viewed 491

I'm using the latest version of Pycharm, 2020.2.2 and django 3.1.

In my project, I removed the default settings.py and created a directory named settings, so the whole project root looks like:

tsetmc
├── asgi.py
├── celery.py
├── context_processors.py
├── __init__.py
├── settings
│   ├── base.py
│   ├── __init__.py
│   ├── local.py
├── urls.py
├── views.py
└── wsgi.py

and in the base.py, I defined the static files setting as:

from pathlib import Path

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

...

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    BASE_DIR / 'assets/'
]

STATIC_ROOT = BASE_DIR / 'staticfiles/'

MEDIA_URL = '/media/'

MEDIA_ROOT = BASE_DIR / 'media/'

Everything works fine in the browser and the static files are successfully loaded using the {% static %} tag; However, Pycharm can not resolve any of the static files in the templates.

I enabled Django Support, set Django project root and settings in the Pycharm settings accordingly and also set the Template Language as Django; but it didn't solve the issue.


After some trial-and-error, I found an odd solution; If I use import os and os.path.join() to locate the static paths, instead of from pathlib import Path and /, Pycharm can resolve the static files without any problem.

So when I changed my base.py to look like this:

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'assets')
]

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles/')

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

(after invalidating the cache, without changing any other configuration)

Pycahrm can fully resolve the static files.

What am I missing here? Is there any problem with using Path to address the static files? or the problem is about the Pycharm itself?

Thanks for the help.

1 Answers

This is a known limitation of PyCharm, you can see this 6 years old bug report: https://youtrack.jetbrains.com/issue/PY-13911. Other users have the same problem, for example here: https://youtrack.jetbrains.com/issue/PY-45244.

This is the recommended solution:

Please consider using os.path for BASE_DIR. (...)

I use https://github.com/pydanny/cookiecutter-django for my projects, which uses pathlib in settings. Even the official Django documentation uses pathlib.

That's why I use this hack in settings so that PyCharm can autocomplete and I can use pathlib:

import os
from pathlib import Path


ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent.parent

# my_project/
APPS_DIR = ROOT_DIR / "my_project"

# STATIC
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = str(ROOT_DIR / "staticfiles")

# https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = "/static/"

# https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = [
    str(APPS_DIR / "static"),
    os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'my_project', 'static')
]

Django staticfiles autocomplete

Related