working with django 3.0.5, but i guess this relates also to < django
2.0.
I uploaded my first django app on my providers space, so far everything works.
This is a Server Schema of my Provider...
_
(` ).
( ). .-------. .-------.
_( '`. ----------> | nginx | -----> | httpd |
.=(`( Internet ) '-------' '-------'
(( (..__.:'-' | => php via php-fpm
`( ) ) | => static files
` __.:' ) | => htaccess
--' |
| .--------------.
'----------> | Web Backends |
'--------------'
=> per-user nginx
=> nodejs, python, ruby, ...
=> gogs, mattermost, matrix, ...
However i am still do not understand some Django Static logics. My static files are served via a separate Apache service. My App called blackbird
The following is like a web backend print
blackbird.abc/blackbird_assets apache
blackbird.abc http:8080 Ok, listening : PID 10104, vassalsuWSGI worker 2
This is like my server account dir looks like
User
|
'-blackbird_app
| '- manage.py
'-hmtl <symbolic link to my documentroot>
'- blackbird_assets
'- static_storage
'-production_static
'-css
'-img
If i like to rename my production_static folder on my apache site to hello_static and reboot my app, django did not find the static files. Alright i guess, but on the other hand how could django even find production_static because this are my current settings.py
settings.py Production
DEBUG=false
INSTALLED_APPS = [
<...>
'django.contrib.staticfiles',
]
STATIC_URL = '/static/'
# STATIC_ROOT = ''
# STATICFILES_DIRS = ''
I also tried to set off the whole django.contrib.staticfiles and django can still find production_static without it, but not hello_static
The only time i mention explicit static folders was in Development. Before i collectstatic and uploaded it to my apache folder and via Git my App. Sidenote: i do not have static folders in my blackbird production app folder.
settings.py Development
STATIC_URL = '/static/'
STATIC_ROOT = '/static_storage/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, env('STATICFILES_DIRS'))]
# env('STATICFILES_DIRS') = static_storage/development_static
Question
The Django Doc said STATIC_ROOT is only for collectstatic. So i use it as an export folder in dev. But it seems internally a little bit more is happened? Otherwise Django would not look outside his Project Folder in my Production App for static_storage/development_static but when i set my folder to static_storage/hello_static it missed it to find.
STATICFILES_DIRS - (additional folders) as an option - only relates in reference to collectstatic, or miss i something?
Is django saving the static folder path after collectstatic in the project internally?
Is there a way to set a new explicit static path in production for Django or do i have set alias via apache to a new static folder? I read about it, but first i have to understand the logic of django.
Alright, between Front and Backend i must have overlooked that my uWSGIservice for my App is mapping my static folder / STATIC_URL. I forgot about this.
On the other hand STATIC_ROOT is maybe semantically misleading - unlike MEDIA_ROOT - STATIC_ROOT is only collecting static files in a folder, when collectstatic is executed. I mixed that up. I guess something like STATIC_COLLECT would be more obvious, to differentiate.
However now static and media files are working in my production.
Soltuion
blackbird_app.ini (uWSGI)
set-placeholder = var_static=/home/user/html/blackbird_assets
<...>
static-map = /static=%(var_static)/static
static-map = /media=%(var_static)/media
<...>
Whenever Django uses STATIC_URL or MEDIA_URL uWSGI will map everything i put in my apache.
setting.py
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print("BASE_DIR:", BASE_DIR)
# Server Base Level or Project Dev Map
SERVER_DIR = os.path.dirname(BASE_DIR)
print("SERVER_DIR:", SERVER_DIR)
<...>
> settings.py
# --- STATIC_URL
STATIC_URL = '/static/'
# --- STATIC_ROOT
STATIC_ROOT = os.path.join(SERVER_DIR, env('STATIC_ROOT'))
print("STATIC_ROOT:", STATIC_ROOT)
# --- STATICFILES_DIRS
STATICFILES_DIRS = [os.path.join(SERVER_DIR, env('STATICFILES_DIRS'))]
print("STATICFILES_DIRS:", STATICFILES_DIRS)
# -- MEDIA_URL
MEDIA_URL = '/media/'
print("MEDIA_URL:", MEDIA_URL)
# -- MEDIA_ROOT
if DEVELOPMENT_MODE == True:
MEDIA_ROOT = os.path.join(SERVER_DIR, env('MEDIA_ROOT_DEV'))
else:
MEDIA_ROOT = env('MEDIA_ROOT_PROD')
print("MEDIA_ROOT:", MEDIA_ROOT)
print("\n")
I used that much print() to track the issue. On the other hand, from now on i will use it to get a better view in my app logs
.env
i use django-environ to set my vars.
<...>
STATICFILES_DIRS=dev_static
STATIC_ROOT=static_root
MEDIA_ROOT_DEV=media_root
MEDIA_ROOT_PROD=/var/www/virt/user_name/html/blackbird_assets/media
<...>
At first i had an Issue with MEDIA_ROOT_PROD because i did not understand how to name the path correctly. My Provider for example used something like /home/virt/.... in the Doc´s also the Django Doc´s spoke about /var/www/example.com/media/. So i used the path that my SFTP und FTP Client showed me and now it works.
Related
When i run django on uwsgi with;
uwsgi --http :8081 --module proj1.wsgi
It gives below error when i open start page from browser:
Not Found: /accounts/login/static/css/style.css
But my settings.py is :
STATIC_URL = 'static/'
STATIC_ROOT = '/home/proj1/static/'
STATICFILES_DIRS = (
'/home/proj1/staticorj/static/',
)
When i make collectstatic, it copies files to static root without problem.
I dont understand why does it look for /accounts/login.
It should look in /home/proj1 directory for static dir.
So the browser opens the page but without serving static files.
Statics operation should be like this.
First configure settings.py like below :
STATIC_URL = 'static/'
STATIC_ROOT = '/home/proj1/static/'
STATICFILES_DIRS = (
'/home/proj1/staticorj/static/',
)
Put statics files that you need in /home/proj1/staticorj/static/
Then run :
python manage.py collectstatic
This will carry /home/proj1/staticorj/static/ files to /home/proj1/static/ directory, and now django will use /home/proj1/static/ directory for static source.
If you will not make any statics changes set as below with commenting.
STATIC_URL = '/static/'
#STATIC_ROOT = '/home/proj1/static/'
#STATICFILES_DIRS = (
# '/home/proj1/staticorj/static/',
#)
And run your server. Better use uwsgi and nginx like apps to serv. In production files will be served. Also use new version browser.
I've been trying to deploy my site this weekend and have thus been meddling with the settings. One of the unpleasant surprises while doing this has been that my static files have seemingly stopped working on my site. My CSS files and javascript files don't work anymore, as if they aren't found by the site. The only thing I can remember doing with regards to static files was inserting this into settings.py:
# The absolute path to the directory where collectstatic will collect static files for deployment.
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# The URL to use when referring to static files (where they will be served from)
STATIC_URL = '/static/'
I removed these settings and replaced them with the original
STATIC_URL = '/static/'
but alas, the problem remains. Why isn't Django finding my static files anymore?
PS: As I'm a noob, I don't know exactly what is relevant from my project for you guys to see, but do let me know and I shall provide additional info.
Okay, update your settings.py as below:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static_my_proj"),
]
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_cdn", "static_root")
Now, that you have done that make dir called static_my_proj, at the same level where your manage.py file is.
Okay, now create new dir called static_cdn just one level up, i.e. one level up to manage.py file.
Now, create dir called static_root inside static_cdn and that is all you have to do. Make sure you run python manage.py collectstatic
NOTE:
static_my_proj is for development or DEBUG = True and static_cdn is for production or DEBUG = True. handy, right?
Also, you can add media file the same way, just add,
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_cdn", "media_root")
and make new dir called media_root under static_cdn.
EDIT:
Copy all your admin files to static dir manually.
If you have virtualenv than go to <virtualenv-dir>/lib/python3.6/site-packages/django/contrib/admin/static and copy dir named admin.
It should work even if DEBUG=False
Hope this helps.
I have a working app and have downloaded the relevant django files locally (via git) and am trying to run the app locally. However, static files are not loading.
I receive the following console error when accessing, say, the home page (http://localhost:8000/home/) of the app:
GET http://localhost:8000/static/imported_JS/jquery/jquery.min.js net::ERR_ABORTED
or this error:
http://localhost:8000/static/globe.png 404 (NOT FOUND)
In my settings.py file, I can confirm:
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)),'..')) # i.e. location of settings.py file
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn/')
I can also confirm there is indeed a static_cdn/ file directory and it does contain the relevant static files.
The live dev and prod versions of the app work (which are hosted on separate web servers) but, for whatever reason, when running the app locally, static files are not served.
Any ideas on how to have the localhost server static files? Most of the answers on SO regarding this type of question relate to mistakes with setting up STATIC_URL vs. STATIC_ROOT but these appear to be correct (at least on dev and prod).
Let me know if you require more info. Thank you.
UPDATE
Well, I struggled with this problem for an hour or so, and 5mins after posting this SO question, I think I found a solution.
Changing from this:
STATICFILES_DIRS = []
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn/')
to this made the difference:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static_cdn/') # add STATIC_ROOT to DIRS
]
STATIC_URL = '/static/'
# STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn/')
I'm not sure why this works but I'll indicate your response as Answer if you explain why. Thanks.
I have two directories called media and static.
When I have DEBUG = True everything works but if I change it to DEBUG = False the problems arises.
I've read that my server will handle static files in production. I have understood it as
In development it's fine to have all my static files in my directory static but when I go in production I need to move all my static files to another directory (it could be static_www?) and before starting the server I run python manage.py collectstatic. This command will move all the files from static_www to static and everything works.
But why do I need to have two separate directories with same content? How do the server know that my files 'has been collected' through collectstatic (it's just files in a folder so how can it know the difference)? I guess collectstatic is primarily used when you have static files in multiple directories and want to collect them all before you go into production.
The variables in my settings.py looks like:
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static_www"),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = '/media/'
and it moves from static_www to static so neither in production nor development my directory static_www is not used.
Maybe all these settings are meant for websites which has another server only for handling static files?
STATIC_ROOT is where the virtual directory for STATIC_URL will point.
Example:
STATIC_ROOT = '/var/www/example.com/static/'
STATIC_URL = 'http://www.example.com/static/'
collectstatic will find all static files in STATICFILES_DIR and copy to STATIC_ROOT.
A request to http://www.example.com/static/file.jpg will be handled by Django and /var/www/example.com/static/file.jpg will be served.
You can set your static files to be even in another site, using something like:
STATIC_ROOT = '/var/www/static.example.com/static/'
STATIC_URL = 'http://static.example.com/static/'
In this way, static.example.com can be a simple server which will serve files without they be handled by Django, increasing the site performance. Or you can upload to a CDN like Amazon S3 (and CloudFront), etc.
I've having a little issue with Django's staticfiles app.
I have added
'django.contrib.staticfiles',
to my INSTALLED_APPS and have added
STATIC_URL = '/static/'
STATIC_ROOT = '/Users/kevdotbadger/django/mylook/static/'
to my settings.py file.
All my static files are located within the STATIC_ROOT folder on my Mac.
Now, within my template I use
{{ STATIC_URL }}
which correctly renders to /static/.
However
{{ STATIC_URL }}css/style.css
result in a 404 error. I'm using the 'runserver' command as the server.
Is there something I'm missing?
I implore you to read the howto docs here: http://docs.djangoproject.com/en/dev/howto/static-files/
In short: STATIC_ROOT is only used if you call the collectstatic manangement command. It's not needed to add the directory to the STATICFILES_DIRS setting to serve your static files!
During development (when the automatic serving view is used) staticfiles will automatically look for static files in various locations (because you call its "serve" view with a path to a static file). For this search it'll use the so called "finders" (as defined in the STATICFILES_FINDERS setting).
One of the default finders is the AppDirectoriesFinder, which will look in the "/static/" directory of each of the apps of yours INSTALLED_APPS setting.
Another default finder is the FileSystemFinder, which will look in directories you specify in the STATICFILES_DIRS setting.
BTW, both these search patterns are similar to how template loading works.
The same technique will be used when running the collectstatic command, except that it now will collect the files from the various locations (using the same finders as above), putting the found files into STATIC_ROOT, ready for deployment.
If you want just a solution - scroll down to the "Solution".
Overview
I was discovering the same problem yesterday. Here is what I found:
All you need is appropriate static finder, that will find your STATIC_ROOT and all its contents, but there is no such finder. Here are default finders:
django.contrib.staticfiles.finders.AppDirectoriesFinder - search installed django applications dirs for 'static' folder, but most of them use obsolete 'media' folders for now.
django.contrib.staticfiles.finders.FileSystemFinder - use all dirs mentioned in the STATICFILES_DIRS, but you can't add STATIC_ROOT into it.
django.contrib.staticfiles.finders.DefaultStorageFinder - search static in your DEFAULT_FILE_STORAGE which is django.core.files.storage.FileSystemStorage by default and it points to your MEDIA_ROOT
Solution
That's all, no additional choices. There are no choices to use STATIC_ROOT for now (in Django 1.3).
So I've just wrote my own custom finder for these needs:
My custom static finder file: finders.py:
from django.core.files.storage import FileSystemStorage
from django.contrib.staticfiles.finders import BaseStorageFinder
from django.conf import settings
class StaticFinder(BaseStorageFinder):
storage = FileSystemStorage(settings.STATIC_ROOT, settings.STATIC_URL)
settings.py:
STATICFILES_FINDERS = (
'finders.StaticFinder',
)
If you want to use it with another finders - I suggest to put them after it inside STATICFILES_FINDERS
And remember: this solution should be used only in development needs and never on production!
I found a quick and easy workaround to serve project global static files during development:
Start a new app that contains your projects static files (e.g. "manage.py startapp static_content")
Create a folder named 'static' in that app and put your static files there.
Add your new app to the list of installed apps
First of all, make sure that you have static serve enabled in your urls.py FOR DEVELOPMENT ONLY.
Also, you may have an extra slash in there. If your STATIC_URL == '/static/', then
{{ STATIC_URL }}/css/style.css should be {{ STATIC_URL }}css/style.css.
STATIC_ROOT = '/home/ws/be/bla/'
STATICFILES_DIRS = ('/home/ws/be/static/',)
STATIC_URL = '/static/'
This works for me. STATIC_ROOT must differ from STATICFILES_DIRS (Django version 1.4 pre-alpha SVN-16436)