Liam Hanninen
Liam Hanninen

Reputation: 1573

Why does collectstatic copy to wrong directory?

I thought I understood static files, collectstatic, etc. But this has my head spinning:

In settings.py:

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

Then I run

python manage.py collectstatic

Then I see

You have requested to collect static files at the destination
location as specified in your settings:

    D:\Code\Project\staticfiles

I'm pretty sure at one point I did actually use 'staticfiles'. But now I've changed it to 'static' and it still thinks the destination should be staticfiles. I've deleted the __pycache__ folder and it still doesn't work.

[Updates] I do have a custom settings file. I based it off of Two Scoops where there is a settings folder with a base.py settings and local.py and production.py. I'm running local and local.py only has db creds and DEBUG = True.

I don't have any value for STATICFILES_STORAGE.

If I print STATIC_ROOT I see:

D:\Code\Project\static

[UPDATE] I'm now looking at the source code. self.storage.location on line 161 is imported on line 5 from django.contrib.staticfiles.storage. In storage.py it is set equal to ConfiguredStorage() on line 442. ConfiguredStorage() inherits a class called LazyObject and has a single function called _setup. This is where the trail gets cold for me. I am trying to find out how self.storage.location is defined. But I can't figure out which way to go now - how do I follow the breadcrumbs back to how STATIC_ROOT?

Upvotes: 0

Views: 1427

Answers (1)

JPG
JPG

Reputation: 88429

Since you have two settings, one for production and one for development, you may need to specify the settings module while running the collectstatic command by using --settings flag.

So, try this

python manage.py collectstatic --settings=path.to.settings.module

UPDATE-1

Issue

The issue was in this statement,
django_heroku.settings(locals())

That particular statement takes all the local variables (which is the local()) and create necessary settings for your project.

In that module, we can see these statements,

if staticfiles:
    logger.info('Applying Heroku Staticfiles configuration to Django settings.')

    config['STATIC_ROOT'] = os.path.join(config['BASE_DIR'], 'staticfiles')
    config['STATIC_URL'] = '/static/'

Which means, django_heroku package will set a STATIC_ROOT value for you if you don't have one. (Yeah, you don't have a STATIC_ROOT in your base.py)

Solution

Case 1: Separate STATIC_ROOT for local and production settings

Just overwrite the value of STATIC_ROOT in corresponding settings modules as,

#settings/local.py
STATIC_ROOT = 'static_root_for_local/'

#settings/production.py
STATIC_ROOT = 'static_root_for_production/'

Case 2: Same STATIC_ROOT for all settings

# settings/base.py
# other settings variable
django_heroku.settings(locals())

STATIC_ROOT = 'common_static_root/'  # this statement should be after the "django_heroku.settings(locals())"

Upvotes: 1

Related Questions