I am working on a multi-app website. And I have bunch of noob questions.
My dir structure looks like as below:
/var/www/html/portal
src/
manage.py
portal/
static/
admin/
css/
img/
js/
fonts/
templates/
base.html
homepage.html
venv/
Is my dir structure as per as Django standards?
Are my STATIC files settings correct?
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
Or should it be
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
Should I collectstatic after copying all my static files such as css,js etc or I can do it before copying files in those dirs?
If I do collectstatic without mentioning STATIC_ROOT I get an exception
django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
But when I replace STATICFILES_DIRS with the following, my .css files stop serving. What am I doing wrong?
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
You don't need to run staticfiles when you're running a development server and DEBUG is set to True.
Static and media files can be then served directly via the web process (Docs) with adding these lines to your main urls.py:
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
As to the whole STATIC_URL, STATIC_ROOT, MEDIA_URL and MEDIA_ROOT, they're all related to how you'll serve your app in production, with a proper webserver.
What usually happens then is that the webserver (i.e. Nginx) handles serving files, not the Django app. But the Django app needs to know where are they. So:
STATIC_URL and MEDIA_URL need to be the same in your Django app settings and in your webserver config, for example with Nginx:
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
...
location /static {
alias /home/myusername/myproject/static/;
}
location /media {
alias /home/myusername/myproject/media/;
}
STATIC_ROOT MEDIA_ROOT are 100% about how you want to structure your project on the server. Assuming the above, you need to work out how to point it to /home/myusername/myproject/static/.
Example of my settings:
BASE_DIR = Path(__file__).parent.parent.parent
MEDIA_URL = '/media/'
MEDIA_ROOT = str(BASE_DIR.joinpath('media'))
STATIC_URL = '/static/'
STATIC_ROOT = str(BASE_DIR.joinpath('staticfiles'))
Media files will be directly uploaded to the MEDIA_ROOT, but notice that you need to somehow get the static files from your applications (which could be in a number of folders, a library you use can have some extra static files, Django Admin has then, etc.) to the folder that Nginx is pointed to (which should be the same as STATIC_ROOT). That's where collectstaticfiles comes in and copies all your static files to that directory.
In regards to directory structure, there are differences of opinion on how it should be set up. A quick google search can bring up some websites and discussions on Django project structures. I recommend reading some of the information to determine what is best for your and your project.
The Django documentation has a best practices page as well that is a good resource/reminder. Django Best Practices.
I mainly followed the Two Scoops of Django directory structure. The Two Scoops has helped me a lot in understanding this. My own twist looks something like this.
src/
app/
templates/
app_name/
base.html
other_pages.html
tests/
tests.py
app_files.py
static/
images/
css/
etc..
templates/
global_includes/
include_file.html
base.html
The collectstatic should not effect the serving of your static files during development. From what I have learned, collectstatic is more for when you are serving your static files during deployment from a separate server, or aws, heroku, etc. More info can be found here in the docs: Managing Static Files, staticfiles app, Deploying static files
I have learned that if my CSS files are not serving, it usually has something to do with my path. Chrome developer tools inspect element/console helps me with any path errors.
Have you added
+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
to your your main urlpattern/urls.py?
Here is more information on serving files during development: Serving static files during development.
Lastly check that your BASE_DIR is following the correct path for your project. You may have to change it.
I hope this helps.
Remember that if you have DEBUG set to 'False' it will ignore the staticfiles setting because it is expected that your webserver will be serving this directly. This caught me out a few times until I realized I hadn't updated the staticfiles folder (which I keep in a separate repository for reasons I can't remember now).
This seems to work in current django (2.2) :
from django.conf.urls.static import serve
urlpatterns += [
path(settings.STATIC_URL[1:], serve, {'document_root': settings.STATIC_ROOT })
]
Related
I just started using django and I got confused over the static files. As per this post correct static files setting I understand that STATIC_URL is just like the name. STATICFILES_DIRS is the place where django will look for static files and STATIC_ROOT where the static files will be collected to. For my project I had the following file sys
rest
|__ rest
|__ settings.py
pages
static
|__admin
|__images
|__vendor
|__bootstrap
templates
manage.py
I decided to go for a project based approach when having my folders instead of a per app one. Some stuff was not working with the website landing page I had and I saw that I needed to collectstatic and so I did but I set the path to my already existing static file which did not let me at first but somehow ended up working. Out of nowhere my static folder had admin on it which I assume is from the admin app that comes with django, and my project finally started to work properly which is the confusing part. I decided to follow the post and included in my settings the following
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles/')
Now I have a staticfiles folder along with my static folder. Also within the staticfiles folder I have everything I have in the static folder and that does not seem right and would like to know how to fix this. I am confused and a bit concerned that I will break everything again so any knowledge provided will be helpful.
I have used like this and its working fine:
STATIC_URL = '/static/'
STATICFILES_DIRS =[os.path.join(BASE_DIR, 'static')]
STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
and use to implement code in the main Project urls.py and not in-app urls.py
urlpatterns += static(settings.STATIC_URL, documents_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, documents_root=settings.MEDIA_ROOT)
Got my Django project on a Azure webapp, but when I call on SSH terminal:
Python manage.py collectstatic
It says 252 files copied but my static files are not visible on my templates and static folder in wwwroot its empty...Here's my wwwroot structure:
wwwroot
|---Myproject
|---manage.py
|---oryx-manifest.toml
|---hostingstart.html
|---static //With all my static files
├── myapp
│ ├── migrations
│ ├── __pycache__
│ ├── static
| | |---Images
| | | |--myimage.png
| | | |--myimage2.png
│ └── templates
And this is my settings.py:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
('myapp', os.path.join(BASE_DIR, 'myapp', 'static')),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
Any idea why or what am I doing wrong ?, does Azure collect different ?
EDIT> When I go to my website my images don´t show...Im calling them like this on template:
{% load static %}
<img src="{% static 'Images/myimage.png' %}" /><br>
EDIT 2 /////
In wwwroot creates indeed a folder with all my statics, but when I load my template they don´t show, in wen console I get this error for myimage.png and myimage2.png :
Failed to load resource: the server responded with a status of 404 (Not Found)
Found it !!
Just had to add this: + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) to url patterns like this:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('myapp/', include('myapp.urls')),
path('admin/', admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
And it did the trick, hope it helps to anyone else!!
Django does not serve static files in production mode.
The only time it serves static files is when you turn DEBUG = True which is in development mode and this is not recommended in a production setting.
Django recommends to serve static files via CND or any other webserver. However if your website is minimal and does not get high volume traffic you can serve your static files using Django whitenoise and here is how you do it.
The below solution works on python 3.7 and Django 3.2
Step 1: Install whitenoise package
pip install whitenoise
Step 2: Ensure your BASE_DIR looks like the below
BASE_DIR = Path(__file__).resolve().parent.parent
Step 3: Add these to your settings.py. If you get any errors try commenting out STATICFILES_STORAGE and check
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Step 4: WhiteNoise middleware should be placed directly after the Django SecurityMiddleware (if you are using it) and before all other middleware
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ...
]
Step 5: Ensure this is how you reference static files in your templates(also check if you have {% load static %} mentioned in your template
<link rel="stylesheet" type="text/css" href="{% static 'appname/styles.css' %}">
Step 6: Run collect static
python manage.py collectstatic
Step 7: Turn DEBUG = False and run the server to verify it works.
Some additional resources to read further:
whitenoise
Django on Azure - beyond "hello world"
Few points to note:
Below line will change
STATIC_ROOT = (os.path.join(BASE_DIR, 'Myproject/static_files/'))
to
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
You are using pointing to completely different folder here. Hence always empty You need the collectstatic command to copy files to
Project > static directory
Below remove the line os.path.join(BASE_DIR, 'static/')...
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static/'), #Not Required since you already mentioned it in STATIC_URL
('myapp', os.path.join(BASE_DIR, 'myapp', 'static')),
)
Reason:
STATIC_ROOT is the folder where static files will be stored after
using manage.py collectstatic
The absolute path to the directory where collectstatic will collect
static files for deployment.
If the staticfiles contrib app is enabled (default) the collectstatic management command will collect static files into this
directory. See the howto on managing static files for more details
about usage.
STATICFILES_DIRS is the list of folders where Django will search for
additional static files aside from the static folder of each app
installed.
This setting defines the additional locations the staticfiles app will
traverse if the FileSystemFinder finder is enabled, e.g. if you use
the collectstatic or findstatic management command or use the static
file serving view.
If issue still persists check your static file directory in apache mod_wsgi config file in the server if it is configured properly.
Check this link for help on that >> https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/modwsgi/
Cheers!!!
I would recommend checking out Whitenoise for serving your static files with Django. I haven't had an issue serving them since integrating Whitenoise. Try swapping it out with your current static file finders setup.
http://whitenoise.evans.io/en/stable/django.html
Settings.py file in Project directory :
I already added following :
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
-> in template
<script src="{% static "validateurl/home.js" %}"></script>
I have a directory static under project directory. home.js is under validateurl directory under static.
Referring JS File using following in template html file :
Please advise what am I missing here.
Errors below :
Here are the steps to configure your django app to serve static files for local development.
The STATIC_ROOT default is None so you have to specify that in settings. Make sure you have something like this in your settings.py This tells your webserver where to find and serve the static file mapped to a url.
import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Second also specify your STATIC_URL variable as it also defaults to none. following should suffice. This will be used for setting up the urlpattern.
STATIC_URL = '/static/'
You need to have a url pattern so your server knows what url corresponds to the static files
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Specify STATICFILES_DIRS variable in settings. So that the collect static manager knows where to find statics and put them in the STATIC_ROOT. This can be an array or tuple of items to different directories. This can be empty if you have no additional directories
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'pathtohomejsdirectory/'),)
Finally, make sure you run python manage.py collectstatic
This copies all the files specified in STATICFILES_DIRS over to the /static/ (STATIC_ROOT) directory to be served by django.
On a production, you want your webserver/reverse proxy say nginx or apache to serve the files. See here django documentation here
I'm trying to configure Django to serve static files when using runserver (production works fine). Everything works fine for all of the static files that are under an apps directory. The problem comes with static files that are not under a specific app, but are in the final static directory. For instance, I have this project structure:
/myproject/
/myproject/static/
/myproject/static/css/foo.css
/myproject/app1
/myproject/app1/static/css/bar.css
urls.py
if settings.SERVE_STATIC:
urlpatterns += patterns('',
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT}),
)
urlpatterns += staticfiles_urlpatterns() # one of these may be redundant.
settings.py
SERVE_STATIC = True
PROJECT_ROOT = '/myproject'
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(PROJECT_ROOT, 'static'),)
INSTALLED_APPS = ('app1',)
With these settings, I get the error:
ImproperlyConfigured: The STATICFILES_DIRS setting should not contain
the STATIC_ROOT setting
Which makes sense. I'm telling Django to collect static files, and put them in the same place - which could cause a loop.
If I comment out the STATICFILES_DIRS variable, django will find the static file 'bar.css'. But it does not find 'foo.css'.
If I comment out the STATIC_ROOT variable and put back the STATICFILES_DIRS, then it finds the file 'foo.css' - but of course, the 'collectstatic' command will no longer work.
Note - I realize that the '/static' directory is supposed to be empty, but the project I'm on, has files there anyway. :) As long as they're not overwritten by 'collectstatic', it looks like Django runserver should serve them - but it doesn't.
How do I serve the static files under STATIC_ROOT (such as foo.css) when running Django runserver?
Move the files that are in /static/ right now to a different directory -- call it /project-static/, for instance.
Then only include this line in urls.py:
urlpatterns += staticfiles_urlpatterns()
(remove the django.views.static.serve view)
And in settings.py, use this:
STATICFILES_DIRS = (os.path.join(PROJECT_ROOT, 'project-static'),)
Then you can put files in /project-static/ directory on your filesystem, the development server will serve them out of the /static/ URL prefix, and in production, collectstatic will find them and put them into the /static/ directory where the web server can find them.
I'm having trouble serving static files in development mode in Django. I do know that this is not a setting that should be used in a production server, so don't worry. For now however I'd like to stick to it.
The relevant parts of settings.py are:
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(os.path.abspath(os.path.dirname(__file__) + '/..'), 'media')
STATIC_ROOT = os.path.join(os.path.abspath(os.path.dirname(__file__) + '/..'), 'static')
And of urls.py:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
So the static files are located for now in the directory named static right outside the project folder. I verified that STATIC_ROOT is evaluated to an appropriate value. I've double checked that the folder exists.
However when pointing my browser to the address localhost:8000/static/js/somefile.js, I get the dreaded 404 Page Not Found with the message 'js/somefile.js' could not be found.. Could you please suggest some reasons to this behaviour?
Thanks in advance.
EDIT:
I think I know where the problem may be: The thing is that in development mode Django attempts to look for the files from the STATIC_URL in the static/ subdirectories of all the installed apps. However I've added some additional files to my STATIC_ROOT and these are not served at all. Maybe there is some clash.
EDIT (2):
This must be it. When I run the server with ./manage.py runserver --nostatic it works, that is it actually serves the files from the STATIC_ROOT directory. What can I do about it? The problem is that just as I try to keep all my template files separate from the project itself I try to do the same with certain css and js files...
It doesn't work, because what I was trying to do wasn't very wise.
That's how it should be configured. settings.py:
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
MEDIA_ROOT = 'media.mydomain.com'
STATIC_ROOT = 'static.mydomain.com'
STATIC_DIRS = (
os.path.join(os.path.abspath(os.path.dirname(__file__) + '/..'), 'static'),
)
All the files remain in place, exactly where they were.
I had a similar problem, adding an explicit reference to the media location in my urlconf as per this fixed the problem for me.