I just setup a simple Django website for development, and commented out
path('admin/', admin.site.urls),
with STATIC_URL = '/static/' in the settings.py,
When I do python manage.py runserver 8100 and goto http://localhost:8100/static/admin/css/nav_sidebar.css, I see
this static file is magically severed.
What's really going on? I have not setup the static url serving in my urls.py yet? I also do not have another static server like NGINX.
I think the static files are served by e.g. NGINX. They are put to a location where they are accessible once you execute python manage.py collectstatic , and then Django does not care about them any more, because they are taken care off by your server. They are outsourced, so to say. Its a different service that handles them. So, the /static will be remain accessible regardless of the admin URLs. What you switch on and off with the admin URLs are the pages under /admin.
http://localhost:8100/admin
Will not work anymore, but
http://localhost:8100/static/admin
will stay untouched.
So from https://docs.djangoproject.com/en/3.2/howto/static-files/, when you set DEBUG=True, Django will automatically do collectstatics and server the static file thur the URLs for you.
Related
I have a Django server running with nginx and gunicorn.
All static files are served correctly, only the admin page has no css, js, etc. .
I already ran collectstatic and restarted nginx and gunicorn.
Nothing changed.
What can I do?
Make sure to mention the locations of your staticfiles_dirs in settings.py. Also remember to mention the locations of your static files in a dynamic format instead of hard coding them in your html document.And make sure to load static in base.html.
Try using this sample code in your settings.py file:
STATIC_URL = '/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'templates'),
'/var/www/static/'
]
STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
After this use the following command in terminal:
python manage.py collectstatic
This should create the static folder and copy all the static objects inside
I am using Django 2.2. From the Django Managing static files documentation:
If you use django.contrib.staticfiles as explained above, runserver
will do this automatically when DEBUG is set to True. If you don’t
have django.contrib.staticfiles in INSTALLED_APPS, you can still
manually serve static files using the django.views.static.serve()
view.
This is not suitable for production use! For some common deployment
strategies, see Deploying static files.
For example, if your STATIC_URL is defined as /static/, you can do
this by adding the following snippet to your urls.py:
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)
Note
This helper function works only in debug mode and only if the given
prefix is local (e.g. /static/) and not a URL (e.g.
http://static.example.com/).
Also this helper function only serves the actual STATIC_ROOT folder;
it doesn’t perform static files discovery like
django.contrib.staticfiles.
My Interpretation
static is a helper function that serves files from the STATIC_ROOT during development (is this True?)
static only works when debug = True
static only works with a local prefix like STATIC_URL = '/static/'
When DEBUG is set to True and I use and setup the staticfiles app as explained in the documentation, if I do python manage.py runserver to start the local server, the serving of static files will be handled automatically (true??)
My Questions
What EXACTLY does adding static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) to your project's urls.py DO?
Is it true that static serves static files locally from the STATIC_ROOT directory? To test this theory, after running collectstatic, I then deleted the static directories to see if the static files still load fine (from the STATIC_ROOT) and they DON'T! Why?
How can I verify that Django is loading the static files from my STATIC_ROOT location... and not the static directories in my project and apps??
Why is adding static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) to urlpatterns necessary if Django serves static files automatically (mentioned in documentation)?
Example
settings.py
DEBUG = True
...
INSTALLED_APPS = [
'django.contrib.admin',
...
'django.contrib.staticfiles',
'puppies.apps.PuppiesConfig'
]
...
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
STATIC_ROOT = 'c:/lkdsjfkljsd_cdn'
In all my templates, I'm using {% load static %}.
Then I do: python manage.py collectstatic
At this point, it doesn't seem to matter if I have the below in my urls.py or not - my static files still load BUT I don't know if they're coming from my project's static directories or my STATIC_ROOT (c:/lkdsjfkljsd_cdn):
if settings.DEBUG is True:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Lastly, if I delete those static directories in my project, all css, js and images don't work which leads me to believe that my Django project is loading static files from my project's static directories, NOT the STATIC_ROOT.
So, again, how can I tell Django to load the static files from my STATIC_ROOT location... and not the static directories in my project and apps?? OR, do I misunderstand that Django isn't supposed to load files from my STATIC_ROOT location locally?
*Edit (adding HTML image)
I think you are mixing up few things. Let me clarify.
static:
As per documentation, it provides URL pattern for serving static file. If you go to the implementation, then you will see:
return [
re_path(r'^%s(?P<path>.*)$' % re.escape(prefix.lstrip('/')), view, kwargs=kwargs),
]
What it does is, it removes forward slash from left of the prefix(ie converts /static/ to static/), and then there is a view(which is serve) who does the pulling files.
serve:
This function does the serving files. It will serve files from a document root.
runserver:
runserver command runs the django development server. If you have django.contrib.staticfiles installed in INSTALLED_APPS, then it will automatically serve static files. If you don't want to serve static, then use runserver --nostatic. collectstatic or STATIC_ROOT has no relation to this command.
collectstatic:
This command collects all static files from different STATIC_DIRS, and put them in folder which is defined by STATIC_ROOT. collectstatic is very useful in production deployment, when you are using a reverse proxy server like NGINX or Apache etc. NGINX/Apache/Varnish uses that folder (where collectstatic stored the static files) as root and serve static from it. It is not recommended to use runserver in production. You can use gunicorn/uwsgi to serve django. But gunicorn/uwsgi does not serve static files, hence using reverse proxy server to serve static files.
finally:
To answer your questions:
No you don't have to put that in your code, unless you are not adding django.contrib.staticfiles in your INSTALLED_APPS.
No
You don't need to. STATIC_ROOT is used for different purpose
It is not. But for serving MEDIA files, you can add the following pattern:
if settings.DEBUG:
urlpatterns += [
re_path(r'^media/(?P<path>.*)$', serve, {
'document_root': settings.MEDIA_ROOT,
}),
]
In production, media files should be served by reverse proxy server as well.
Running Django dev server has no problem: 'python manage.py runserver 9000'
But if use gunicorn, it complains:
'http://innovindex.com/pubmed/static/js/jquery-3.2.1.min.js '
Why gunicorn cannot find a local jquery but Django can?
The settings are:
settings.py (seems not related):
STATIC_URL = '/pubmed/static/'
in '/etc/nginx/sites-enabled/django'
location /static {
alias /home/django/innovindex/pubmed/static/;
}
And my app looks like this:
/home/django/innovindex
is where the 'manage.py' sits.
THANK YOU SO MUCH !!!
From Deploying static files in the Django documentation, you must run the collectstatic command in addition to setting the STATIC_ROOT setting.
First make sure that you're STATIC_ROOT is set to the correct path that matches your nginx config:
STATIC_ROOT = '/home/django/innovindex/pubmed/static/'
Note that this is an absolute path.
Then run:
python manage.py collectstatic
in your project directory.
This will copy all of your static files into /home/django/innovindex/pubmed/static/
I spent a lot of time trying to figure this out until I found that the below must be in your main urls.py. Just add those two lines.
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ...
urlpatterns += staticfiles_urlpatterns()
I've seen lots of different posts regarding the Django static file issues. Unfortunately, none of them seem to help me. My django admin css is fine, however static files are giving my a 404 error. Here is a description of what my problem:
In settings.py:
STATIC_URL = '/static/'
STATIC_ROOT = '/Users/me/develop/ember/myproj/static/'
In urls.py:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
My project directory:
> static
> myproj
> app
> templates
> ember.hbs
> img
> test.jpg
Inside my ember.hbs I reference the test.jpg, but I get a 404 error. It's weird because I can actually pull up the image using:
file:///Users/me/develop/ember/proj/static/myproj/img/test.jpg
I have no idea what to do to fix this, I've tried using the STATICFILES_DIRS method mentioned here: https://docs.djangoproject.com/en/1.8/howto/static-files/
but nothing seems to be working.
Thanks in advance!
More information: Django 1.8 and Ember-CLI.
I'm hosting the ember project within the static dir.
I'm running python manage.py runserver and running django on port 8000 at the same time as running ember s and running the application on port 4200. I'm using CORS-headers (https://github.com/ottoyiu/django-cors-headers/) to allow cross-site calls on development.
Static files will be discovered in "apps" that you create (found in INSTALLED_APPS) or in additional directories that you specify in STATICFILES_DIRS.
Let's say I did:
django-admin.py startproject myproject
And then:
cd myproject
./manage.py startapp myapp
mkdir myapp/static
mkdir myproject/static
Would give you a directory structure that looks something like
/Users/me/develop/myproject/
> myapp/
> migrations/
> static/
> __init__.py
> admin.py
> models.py
> tests.py
> views.py
> myproject/
> static/
> __init__.py
> settings.py
> urls.py
> wsgi.py
> manage.py
And then in settings.py you add "myapp" to INSTALLED_APPS.
In this structure, myapp/static/ files will be automatically discovered by Django because it is an installed app with a static directory. However, myproject/static/ files will NOT be discovered automatically because "myproject" is not in INSTALLED_APPS (and it shouldn't be).
This is because of the default STATICFILES_FINDERS setting, which is:
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'django.contrib.staticfiles.finders.FileSystemFinder',
]
The first finder, AppDirectoriesFinder, scans the directories of all of your INSTALLED_APPS, and discovers any "static" folders they might contain.
The second finder, FileSystemFinder, scans extra directories that you specify in STATICFILES_DIRS, which is an empty list by default.
So if you want those files in /Users/me/develop/myproject/myproject/static/ to be discovered (as you probably do), you can add this to your settings.py:
from os import pardir
from os.path import abspath, dirname, join
# Get the root directory of our project
BASE_DIR = abspath(join(dirname(__file__), pardir))
# Add our project static folder for discovery
STATICFILES_DIRS = (
# /Users/me/develop/myproject/myproject/static/
join(BASE_DIR, 'myproject', 'static'),
)
Now, all of this is separate from STATIC_ROOT, which is a place where all static files are copied when you run ./manage.py collectstatic. For projects just starting out, this is usually in the project root folder: /Users/develop/me/myproject/static/
So we would add, in settings.py:
# /Users/me/develop/myproject/static/
STATIC_ROOT = join(BASE_DIR, 'static')
But this is only really used in production—it's a way to compile all of your static assets into a single spot, and then point /static/ at it with your server (e.g. NGINX).
During development, you can skip collectstatic altogether, and have Django discover and serve your static assets on the fly. Django provides a "serve" view to do this in django.contrib.staticfiles.views.serve.
Try this in your urls.py:
from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.staticfiles.views import serve
admin.autodiscover()
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
]
if settings.DEBUG:
urlpatterns += [
url(r'^static/(?P<path>.*)$', serve),
]
In your example, you are asking Django to serve files from STATIC_ROOT, which is also fine, but requires you to run ./manage.py collectstatic first, and every time your static assets change—which can be a hassle.
Ember and Django really shouldn't live in the same project. They are completely different frameworks with different tooling.
Think of your Django project as the backend application that serves an API. Think of your Ember project as one of possibly many clients that will consume your API. Others might include mobile applications, partner services, and so on.
When I start a new project that is going to use Django and Ember, I start a Django project called "myproject":
django-admin.py startproject myproject
And separately, an Ember project called "myproject-web":
ember new myproject-web
In development, I'll have two tabs open in Terminal.
First tab:
cd myproject
./manage.py runserver
Second tab:
cd myproject-web
ember serve
In production, I'll have two different servers, one at app.myproject.com that serves the Django application, and another one at myproject.com that serves the Ember application.
Later on, I might start a Swift project in a repository called "myproject-ios", and a Java project called "myproject-android". You get the idea.
In order to serve the static files into your django project you just need to add these lines to your `settings.py
STATIC_URL = '/static/'
STATIC_PATH = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
STATIC_PATH,
)
and then in the main stucture of your project dictory needs to be like
>Project_dir
>App_dir
>static_dir
>templates
>manage.py
place your css, js, and other static contents into your static_dir
My django project contains a folder STATIC in which there are it's child folders css, images, js and swf. My web-site can not locate these files raising a 404 in the development server running on the terminal.
I have a settings_local.py file in which I have set the path such as (running on ubuntu 11.04)
STATIC_ROOT = '/home/zulaikha/dust.bin/my_project/static/'
STATIC_SERVE_PORT = 80
The sample settings-local.py file from the client suggest suggest so
# static root
STATIC_ROOT = 'C:/Program Files (x86)/XAMPP/htdocs/static'
STATIC_SERVE_PORT = 8080
I have seen some similar issues but all regard STATICFILES which I read was introduced in Django 1.3
Where am I wrong and how can I correct myself?
If you are indeed using django 1.2 then you must install django-staticfiles. If you do not see it in the included requirements.txt from your client then he either did not freeze it out into the file, or was not using that feature and instead was just pointing at it via apache or another production server.
Follow these instructions from the docs. Specifically the basic section:
https://docs.djangoproject.com/en/dev/howto/static-files/
You will need to add staticfiles to your installed app. You should also not need to manually add a url since the django should do it automatically with the runserver command.
Also verify that it works locally first by not running with sudo or a custom ip and port
According to your comments there are two options here:
Contact the programmer who wrote the code and ask him.
Rewrite static serving logic with
django-staticfiles (Django 1.2 is enough)
django.contrib.staticfiles and Django 1.3
In the simplest form, this is the solution to the problem. In project urls.py include the following lines
urlpatterns += patterns('',
url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.STATIC_ROOT,
}),
)