I am currently working through some tutorials to enhance my knowledge of Django. In doing so, I decided to use to most recent version of Django. I have been able to overcome most of the divergences between my code and that of the tutorial except for one - static files are not being served. Now, I am not fully sure that the difference is strictly due to the Django version. Here is what is going on.
I have the following project structure:
settings.py
STATIC_URL = '/static/'
STATIC_FILES = (
os.path.join(BASE_DIR, "static"),
)
STATIC_ROOT = os.path.join (os.path.dirname(BASE_DIR), "staticfiles", "static")
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "templates")],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
What is interesting is that with this configuration, the project is able to find templates successfully. However, as mentioned above, it cannot find the static files. Why is that?
Also, this tutorial sets up an unusual configuration in that the static and templates directories are located inside the main app's directory, whereas I typically have them one level higher, i.e., in the project root's directory. Could this be a part of the problem? What in the settings of this particular project makes Django look for files one directory lower? The settings seem the same as those of other project I had done. However, those project contained the static and templates directories in the project's root directory.
Any help and clarification is appreciated.
Edit:
urls.py
from django.contrib import admin
from django.urls import path
from .views import home
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', home, name='home')
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
try replacing this:
STATIC_ROOT = os.path.join (os.path.dirname(BASE_DIR), "staticfiles", "static")
with
STATIC_ROOT = os.path.join (os.path.dirname(BASE_DIR), "static")
Also provide the status of files (like 404 messages)
STATIC_FILES doesn't mean anything to Django, as far as I know, although maybe you are using it for another purpose.
The way you had STATIC_ROOT defined it was pointing to a non-existent directory.
There is a good reference in StackOverflow here
To serve static files you need to add the following configuration in urls.py as:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Next, I believe it is a good practice to put static and templates within their own apps, this is useful if you want to make that app plug-able any near future.
Or it is also a good practice to gather all static files in project level directory and add the following in settings to identify it.
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
edit: I just see the updated question. Try adding this:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', home, name='home')
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
This says, as long as we are in debug mode serve the static files.
try this:
STATIC_ROOT = os.path.join (BASE_DIR, "taskbuster", "static")
I was able to solve the issue by changing the settings to the following:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
STATIC_ROOT = os.path.join (os.path.dirname(BASE_DIR), "static")
Furthermore, it was helpful to read the following documentation when trying to understand how to fix it
https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-STATICFILES_FINDERS
Particularly, this explained clearly what Django did:
The default will find files stored in the STATICFILES_DIRS setting
(using django.contrib.staticfiles.finders.FileSystemFinder) and in a
static subdirectory of each app (using
django.contrib.staticfiles.finders.AppDirectoriesFinder). If multiple
files with the same name are present, the first file that is found
will be used.
Related
Problem: None of the changes I'm making to my CSS files are being applied to my HTML pages. And when I try and make new HTML/CSS files I get errors when I inspect the page in developer mode. The errors are saying they can't find my CSS files.
Exact error when I inspect my page in developer mode
GET http://127.0.0.1:8000/static/css/other.css net::ERR_ABORTED 404 (Not Found)
Background:
I'm creating a basic image editing site using django, html/css, and injecting JS to apply some filters to images. Previously I was able to make changes and they were reflected in the page, but now I can even delete my css file and it still uses an older version.
Things I've tried:
Gone into settings cleared browser cache
Disabled caching in developer mode
appended the version of css file ?v1.1 to force a rest (caused the 404 error from above)
Run collectstatic in terminal
Cleared cache opened site in private window
Watched several youtube vids on setting up static file dir and I think its correct. At some point in time my css was loading and updating as I made changes.
Directory Layout
These are my settings
Settings.py
BASE_DIR = Path(__file__).resolve().parent.parent
DEBUG = True
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'Image_API',
'rest_framework',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'Image_API.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates']
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
STATIC_URL = 'static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, '../static'),
]
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), '../static')
Urls.py File
from django.contrib import admin
from django.urls import path
from Image_API import views
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
path('',views.upload2, name='upload'),
path('upload/', views.upload2, name='upload'),
path('other/', views.other),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root =settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()
How my HMTL Files refrence css
I have load static at the top of the page and have my link to the css in the header tag.
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static '/css/style.css' %}">
It looks like the problem might be coming from your STATIC_URL setting and or STATIC_ROOT. Try changing it to:
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
You might also want to check that your urls.py file is setup correctly:
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Restart your server after making these changes just to be sure.
ps: collect static is run during deployment
You might have overlooked and updated CSS in /staticfiles/css/
Instead try updating it in /media/css.
staticfiles directory is auto-generated when you run python manage.py collectstatic.
You can try deleting staticfiles directory and run python manage.py collectstatic and see if it fixes the issue.
This is the first web application I'm developing by combining django and reactjs, in fact react is new to me.
Please if my approach is wrong I'm open for correction.
When developing with purely django, I find no difficulty with static and media files.
It is clear that the elements involved are the media root and static root,
respectively. In that case, all I need to do is to specify the static/media root in the
settings.py in the django app as shown below:
settings.py
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/images/'
urls.py
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \
+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
However, when I combine django and react the configuration changes since django is configured
to look at index.html file in react, in which case an additional element called STATICFILES DIRS
is added to the seetings.py file to specify the path to react index.html. In fact, my django app
configuration looks like this when I combine django and react:
settings.py
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'build/static')]
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/images/'
urls.py
urlpatterns = [
...
re_path(r'^.*', TemplateView.as_view(template_name='index.html'))
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \
+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'build')],
...
]
Everything works well as when I'm developing purely with django except that when I combine django and react in development the images I upload refuse to displayed
on the browser since any path that does not match with the specified paths in urlpattern are redirected
to react. re_path(r'^.*', TemplateView.as_view(template_name='index.html')) So the image path is being redirected. When I click the image link in the admin file, instead of
the image to get displayed, I'm redirected to react also. I have made research online but I can't find any resources
that explained properly how to configure the django static root and media root to be able to serve files (
like images uploaded to the database) content.
Please, do I display images and media on the browser? In production, I would like to serve static files of the
django-react app with aws s3 bucket
Check that you have added the build folder to installed apps
INSTALLED_APPS = [ build, ]
If DEBUG use STATICFILES_DIRS else use STATIC_ROOT. Add this code in the settings.py file.
if DEBUG: STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] else: STATIC_ROOT = os.path.join(BASE_DIR, 'static')
In the urls.py file
urlpatterns += [re_path(r'^.*', TemplateView.as_view(template_name='index.html'))]
Then run python manage.py collectstatic
You should also install whitenoise pip install whitenoise
I am ashamed to ask a question of that sort but I still can not solve my problem. I normally uploaded image in my media directory and can see image link in my admin but if I click on link I get:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/photo/img/9.jpg
Using the URLconf defined in TeamStudy.urls, Django tried these URL patterns, in this order:
^admin/
The current URL, photo/img/9.jpg, didn't match any of these.
my project structure:
src
static/
photo/
img/
settings:
PROJECT_DIR = os.path.dirname(os.path.dirname(__file__))
BASE_DIR = os.path.dirname(PROJECT_DIR)
MEDIA_ROOT = os.path.join(BASE_DIR, 'static', 'photo')
MEDIA_URL = '/photo/'
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static")
STATIC_URL = '/static/'
urls.py
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
]
I suspect it perhaps quite simple and I miss something. Please point me.
You need to add the media MEDIA_ROOT and MEDIA_URL in your urlpatterns
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
check following links for more details
Accessing "Media" files in Django
Django classifies user files in two types
Static files
Media files
this link helps you understand the difference between them
Your issues deals with Media files.
In future development, you may need to serve static files, to serve them you will need to add
STATIC_ROOT and STATIC_URL to the urlpatterns in a similar way that MEDIA_ROOT and MEDIA_URL are added
Change your URL's patterns:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
for more info Django Docs
First point: don't put uploaded medias in you static directory - static is for static files that are part of your project (css, js etc) -, you want to use MEDIA_ROOT and MEDIA_URL for this.
wrt/ serving the static and media contents, it depends on the environment. On your local dev environment you want to use the staticfile.views to serve both static and medias as mentionned in the other answers, but don't do this in production : on a production server, you want to use your front web server to serve static (and media) contents.
I have CSS file at /ecomstore/static/css.css
I have already linked the css to the base.html within head tags by
<link rel="Stylesheet" type="text/css" href="/static/css.css" />
My urls.py file:
from django.conf.urls import include, url
from django.contrib import admin
from ecomstore import settings
from django.contrib.staticfiles import views
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^catalog/','preview.views.home'),
# url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
# { 'document_root' : '/home/yogesh/ecomstore/static' })
]
urlpatterns = [
# other commented code here
url(r'^catalog/?','preview.views.home'),
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',{ 'document_root' : '/home/yogesh/ecomstore/static/' }),
]
Settings.py file
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'DIRS': [os.path.join(CURRENT_PATH, 'templates')],
'DIRS': [os.path.join(BASE_DIR, 'templates/')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Static settings:
STATIC_URL = '/static/'
STATIC_ROOT = "/home/yogesh/ecomstore/static/"
Despite all this stuff i dont know why my css template is not loading. Also in the terminal i am getting the following indicating some sort of error.
[24/Nov/2015 11:11:36] "GET /static/css.css HTTP/1.1" 404 1735
Use {% static %} template tag:
{% load staticfiles %}
Configure static files dir in your settings and do not hardcode the path in your urlconf:
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
'/var/www/static/',
)
Make sure you're serving static files during development:
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Check that static file dir /home/yogesh/ecomstore/static/ is readable by your django process.
Static files
Store your files in /ecomstore/static/ecomstore/css.css instead of /ecomstore/static/css.css because Django look by default in all folders <app_name/static/<app_name>, then you don't have to had these folder in STATICFILES_DIRS variable.
Django documentation :
Store your static files in a folder called static in your app. For
example my_app/static/my_app/myimage.jpg.
Read this for more
information and configure your project : Managing static files
Templates
You did also a mistake in the configuration of your template. When you use os.path.json function, you don't have to have a / at the last folder. Just use os.path.join(BASE_DIR, 'templates')
Serving static file during development
Concerning serving static files, if you use the django built-in server, you don't have to configure anything, Django serve them by default. However, if you use gunicorn or uWSGI, yes you have to configure your project to serve static files.
You have to add this in your main <project_name>/<project_name>/urls.py file:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Now, your server will server static file based on STATIC_URL that you configured in your <project_name>/<project_name>/settings.py file.
Read this for more information : Serving static files during development
Not sure what I'm doing wrong, but I can't get this to work. I'm using Django 1.3 and Python 2.7.
My project structure looks like this:
project
static
templates
settings.py
apps
...
In my settings.py file I have
PROJECT_ROOT = os.path.realpath(os.path.dirname(__file__))
STATIC_ROOT = os.path.realpath(os.path.join(PROJECT_ROOT, 'static'))
STATIC_URL = '/static'
my urls.py file:
from django.conf.urls.defaults import *
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^grappelli/', include('grappelli.urls')),
)
urlpatterns += staticfiles_urlpatterns()
In my templates, I'm using {{ STATIC_URL }} which creates the correct path to my files, like this: /static/js/libs/modernizr-2.0.6.min.js.
None of my static files load and I've double checked the directory structure is correct. I feel like I'm taking crazy pills, so any advice is appreciated. Thanks
You should add the complete path to the dir where you place your static files in STATICFILES_DIRS in settings.py, like this:
STATICFILES_DIRS = (
'/path/to/static',
)
Either add STATICFILES_DIRS as in previous answer or put the package directory that has 'static' dir in your INSTALLED_APPS because django will automatically serve any static dir in apps during development. If your project directory is not on python path and you're not planning to make it importable then you have to define STATICFILES_DIRS and put absolute path to the static directory.