Media files are served, static files aren't - django

I'm stuck due to an evergreen issue, static files not served. Conversely the files placed in the MEDIA_ROOT subtree get served correctly under MEDIA_URL.
Stripped settings.py:
DEBUG = True
STATIC_URL = '/static/'
STATIC_ROOT = '/home/foo/devel/static'
MEDIA_URL = '/media/'
MEDIA_ROOT = '/home/foo/devel/media'
# the following is deprecated but is it seems grappelly requires it
ADMIN_MEDIA_PREFIX = STATIC_URL + "grappelli/"
STATIC_FILES = ()
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
To create the project I did:
$ cd /home/foo/devel/
$ virtualenv testdrive
$ . bin/activate; pip install django; cd testdrive
$ django-admin.py fbtest
and got this directory tree (stripped):
. <-- /home/foo/devel/
├── bin
├── fbtest
│   └── fbtest
│   ├── media
│   │   └── foo.jpg
│   ├── static
│ └────── foo.jpg
├── include
└── lib
Files under STATIC_URL should be served automatically by Django staticfiles (not in my case), while other files have to be handled manually. So I appended these lines to urls.py:
import settings
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^%s(?P<path>.*)$' % settings.MEDIA_URL.lstrip("/"),
'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
)
Accessing http://host/media/filebrowser/foo.jpg works, while http://host/static/foo.jpg gives error 404. Why?

Files under STATIC_URL should be served automatically by Django staticfiles (not in my case), while other files have to be handled manually.
That's incorrect. Django never serves STATIC_ROOT ever -- not even in development. What it does do is make files in each app's "static" directory and files in any directory specified in STATICFILES_DIRS available at STATIC_URL. You don't actually manually put anything in STATIC_ROOT ever; in fact, in development, you shouldn't even have the directory there. Put simply, STATIC_ROOT is only a dumping ground for your static files in production when you run the collectstatic management command.
In development, all static files should go into someapp/static, where "someapp" is the app they apply to. In the case that the files apply to the project as a whole, a global CSS file for example, you need to create an entirely different directory (i.e. not the same as STATIC_ROOT or MEDIA_ROOT) and then add that directory to STATICFILES_DIRS. For example, I normally call mine "assets", so:
STATICFILES_DIRS = (
os.path.join(os.path.dirname(__file__), 'assets'),
)

It was a silly error. I forgot to add fbtest to INSTALLED_APPS, so the static file machinery didn't manage static files for this app.

This problem is realy evergreen...
Some hints:
TEMPLATE_CONTEXT_PROCESSORS = (
# ...
'django.core.context_processors.static',
# ...
)
INSTALLED_APPS = (
# ...
'django.contrib.staticfiles',
# ...
)
Did you use? django-admin-collectstatic command?
Can you help add show_indexes=True in url settings?
Some symbolic link?
Run app with --adminmedia=../grappelli/static/grappelli arg.?
My settings for django 1.4 (no grappelli):
urls.py
if settings.DEBUG:
urlpatterns = patterns('',
url(r'^%s(?P<path>.*)$' % settings.STATIC_URL.lstrip('/'), 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT, "show_indexes": True}),
url(r'^%s(?P<path>.*)$' % settings.MEDIA_URL.lstrip('/'), 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT, "show_indexes": True}),
) + urlpatterns
settings.py
MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media')
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
ADMIN_MEDIA_PREFIX = '/static/admin/'
TEMPLATE_CONTEXT_PROCESSORS = (
# ...
'django.core.context_processors.static',
# ...
)
INSTALLED_APPS = (
# ...
# 'django.contrib.staticfiles',
# ...
)

Related

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

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.
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 is applying background color , but not apllying background image from style.css

I run my django project with uwsgi.
It reads style.css file in statics/css .
There are two areas in style.css
It applies 1st area, but it does not apply 2nd area to the page.
and
1) #skin-blur-violate {
background: #581528;
}
and
2) #skin-blur-violate {
background-image: url(../img/body/violate.jpg);
}
Below is statics configuration in settings.
STATIC_URL = '/home/proj1/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
STATICFILES_DIRS = (
'/home/proj1/staticorj/static/',
)
In your projects urls.py, add this code:
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
And In your settings.py only keep this code regarding Static files & exclude what you have earlier:
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
And, your static folder tree should be like this:
App
├── static
├── app
└── images
└── style.css
See if this works.

Static file management in Django1.4

I've been confused with static files in Django for days. I found one solution that worked fine. But it collapsed when I set DEBUG=False. So I build up a new project and do some tests to get a clearer look.
First I create a project with the default settings. Then I changed some lines of the setting file into:
STATIC_ROOT = '%s/site_media' % PROJECT_DIR
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(STATIC_ROOT, 'images'),
)
After that, I put 'hi.jpg' at 'project_dir/images/hi.jpg'. I call runserver and visit 'http://127.0.0.1:8000/static/images/hi.jpg'. It doesn't work. What's the problem?
Here's how it works: when DEBUG=True then Django serves the static files itself. When DEBUG=False then Django won't do that anymore and you'll need to configure your web server to do it (such as Apache).
Django has a mechanism for that in django.contrib.staticfiles (see Managing static files and The staticfiles app). It basically means that you need to run the collectstaticmanagement command which will search for all static files in /static/ directories in your Django project and it will put them in one directory (STATIC_ROOT). When that has been done, your web server can serve the static files from that directory.
If one or more static files can't be found after running collectstatic then that means you have configured something incorrectly.
settings.py
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
MEDIA_ROOT = os.path.join(PROJECT_DIR, 'site_media')
MEDIA_URL = '/site_media/'
STATIC_URL = '/static/'
if DEBUG:
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
else:
STATICFILES_DIRS = (
os.path.join(PROJECT_DIR, 'static'),
)
urls.py
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
)
:)
Django: Migrating from MEDIA_URL to STATIC_URL

Confusion in Django admin, static and media files

I'm relatively new to Django (1.4) and I'm having a hard time understanding the philosophy behind static, media, and admin files. The structure of the project is different from one tutorial to another, and same thing for Webfaction(where I'll be hosting my application). I would like to know what is the optimal way to organize it and with least pain and editing while deploying it to Webfaction, what is the point of static media, adn admin files?
Thank you in advance
In essence you want to serve static files by django in development. Once you're ready to go into production you want the server to do this for you (they are build to do it fast :-))
Here's a basic setup, once you login the server you run the collectstatic command to get all the staticfiles in the static-root folder, which your server points to (see the rewrite rules)
./manage.py collectstatic
settings.py
from os import path
import socket
PROJECT_ROOT = path.dirname(path.abspath(__file__)) #gets directory settings is in
# Dynamic content is saved to here
MEDIA_ROOT = path.join(PROJECT_ROOT,'media')
# if ".webfaction.com" in socket.gethostname():
# MEDIA_URL = 'http://(dev.)yourdomain.com/media/'
# else:
MEDIA_URL = '/media/'
# Static content is saved to here --
STATIC_ROOT = path.join(PROJECT_ROOT,'static-root') # this folder is used to collect static files in production. not used in development
STATIC_URL = "/static/"
STATICFILES_DIRS = (
('', path.join(PROJECT_ROOT,'static')), #store site-specific media here.
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
settings_deployment.py
from settings import *
DEBUG = False
TEMPLATE_DEBUG = DEBUG
MEDIA_URL = "http://yourdomain.com/media/"
urls.py
...other url patterns...
if settings.DEBUG:
urlpatterns += staticfiles_urlpatterns() #this serves static files and media files.
#in case media is not served correctly
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
)
django.conf (lighttpd, this could be apache or nginx) but I believe webfaction has an app service to set this up easily
$HTTP["host"] =~ "(^|\.)yourdomain\.com$" {
fastcgi.server = (
"/django.fcgi" => (
"main" => (
"socket" => env.HOME + "/project/project.sock",
"check-local" => "disable",
)
),
)
alias.url = (
"/media" => env.HOME + "/project/media",
"/static" => env.HOME + "/project/static-root",
)
url.rewrite-once = (
"^(/media.*)$" => "$1",
"^(/static.*)$" => "$1",
"^/favicon\.ico$" => "/static/img/favicon.png",
"^(/.*)$" => "/django.fcgi$1",
)
}
Static files are files needed by your applications that server can serve without modifications, like custom JS scripts, icons, applets, etc. The best way to use it is to place static files in a "static" folder in each of your app's folder. Like this, the test server will find them there, and if you deploy on a production server, you'll just have to run python manage.py collectstatic to copy them all in the root static folder defined in you settings.py
Media files are those uploaded by the users of your applications, like avatar's pics, etc.
Admin files are static files used by Django admin, django test server will just find them, but on production, you'll have to copy or link to this folder for the admin to actually work.
Hope it helps you see things better...
My config is:
1.settings.py
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT='/media/'
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = '/media/'
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = '/static/'
# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
'/'.join(__file__.split(os.sep)[0:-2]+['static']),
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
2.urls.py
from django.conf import settings
if settings.DEBUG:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
AND my site dir is like this:
root
│ manage.py
│
├─media
├─my_django_py3
│ settings.py
│ urls.py
│ views.py
│ wsgi.py
│ __init__.py
│
├─static
│ 9gq05.jpg
│ ajax.js
│ favicon.gif
│
├─templates
└─utils

How do I serve static files and dynamic files in Django 1.3 development urls?

I'm a little stumped. In development, I'm trying to serve both static AND dynamic files for my app in DJango 1.3. I love the new static features, but I can't seem to get this to work properly.
When I read the docs, it looks like the following should work. It serves dynamic stuff fine, but not static.
urlpatterns += staticfiles_urlpatterns()
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^media/dynamic/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
)
In django 1.3 static and dynamic content have been separated. to use the new features, set up your project like this:
project
|- app1
|- media # exists only on server/folder for dynamic content
|- static-root # exists only on server/folder for static content
|- static # folder for site-specific static content
|- settings.py
|- manage.py
`- urls.py
settings.py
from os import path
PROJECT_ROOT = path.dirname(path.abspath(__file__)) #gets directory settings is in
#-- dynamic content is saved to here --
MEDIA_ROOT = path.join(PROJECT_ROOT,'media')
MEDIA_URL = '/media/'
#-- static content is saved to here --
STATIC_ROOT = path.join(PROJECT_ROOT,'static-root') # this folder is used to collect static files in production. not used in development
STATIC_URL = "/static/"
ADMIN_MEDIA_URL = STATIC_URL + 'admin/' #admin is now served by staticfiles
STATICFILES_DIRS = (
('site', path.join(PROJECT_ROOT,'static')), #store site-specific media here.
)
#-- other settings --
INSTALLED_APPS = (
...
'django.contrib.staticfiles',
...
)
urls.py
from django.conf import settings
#your URL patterns
if settings.DEBUG:
urlpatterns += staticfiles_urlpatterns() #this servers static files and media files.
#in case media is not served correctly
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
)
Check STATIC_URL from settings.py, what is the value ?