In Django, the convention is to put all of your static files (i.e css, js) specific to your app into a folder called static. So the structure would look like this:
mysite/
manage.py
mysite/ --> (settings.py, etc)
myapp/ --> (models.py, views.py, etc)
static/
In mysite/settings.py I have:
STATIC_ROOT = 'staticfiles'
So when I run the command:
python manage.py collectstatic
It creates a folder called staticfiles at the root level (so same directory as myapp/)
What's the point of this? Isn't it just creating a copy of all my static files?
Collect static files from multiple apps into a single path
Well, a single Django project may use several apps, so while there you only have one myapp, it may actually be myapp1, myapp2, etc
By copying them from inside the individual apps into a single folder, you can point your frontend web server (e.g. nginx) to that single folder STATIC_ROOT and serve static files from a single location, rather than configure your web server to serve static files from multiple paths.
Persistent URLs with ManifestStaticFilesStorage
A note about the MD5 hash being appended to the filename for versioning: It's not part of the default behavior of collectstatic, as settings.STATICFILES_STORAGE defaults to StaticFilesStorage (which doesn't do that)
The MD5 hash will kick in e.g. if you set it to use ManifestStaticFilesStorage, which adds that behavior.
The purpose of this storage is to keep serving the old files in case
some pages still refer to those files, e.g. because they are cached by
you or a 3rd party proxy server. Additionally, it’s very helpful if
you want to apply far future Expires headers to the deployed files to
speed up the load time for subsequent page visits.
Django static files can be in many places. A file that is served as /static/img/icon.png could come from many places. By default:
FileSystemFinder will look for img/icon.png in each of STATICFILES_DIRS,
AppDirectoriesFinder will look for img/icon.png in the static subfolder in each of your INSTALLED_APPS. This allows libraries like Django Admin to add their own static files to your app.
Now: this only works if you run manage.py runserver with DEBUG=1. When you go live, the Django process will no longer serve the static assets. It would be inefficient to use Django for serving these, there are more specialised tools specifically for that.
Instead, you should do something like this:
find all of static files from every app
build a single directory that contains all of them
upload them somewhere (a static directory somewhere on your webserver or a third-party file storage)
configure your webserver (such as nginx) to serve /static/* directly from that directory and redirect any other requests to Django.
collectstatic is a ready-made script that prepares this directory for you, so that you can connect it directly to your deployment script.
In the production installation, you want to have persistent URLs. The URL doesn't change unless the file content changes.
This is to prevent having clients to have wrong version of CSS or JS file on their computer when opening a web page from Django. Django staticfiles detects file changes and updates URLs accordingly, so that if CSS or JS file changes the web browser downloads the new version.
This is usually achieved by adding MD5 hash to the filename during collectstatic run.
Edit: Also see related answer to multiple apps.
It's useful when there are multiple django apps within the site.
collectstatic will then collect static files from all the apps in one place - so that it could be served up in a production environment.
Related
I don't seem to understand the issue with serving static files in Python apps, for example Django. Now I am reading a documentation of WhiteNoise and first question is why it was developed in the first place? I mean what problem it solves? Why we can't save all the static files in /static folder and copy it to hosting.
I don't seem to understand the issue with serving static files in Python apps, for example Django.
As is specified in the Django documentation on managing static files:
This method is grossly inefficient and probably insecure, so it is unsuitable for production.
Indeed, Django's views to serve static files are likely not very efficient. A webserver will typically cache a certain amount of files, use compression to send these to the browser (if the browser accepts this), etc. Django's views to serve static/media files are not designed to be competitive with a webserver like apache/nginx.
Even if that is solved, it using a signle server to serve static content is not a good idea. Often Content Delivery Networks (CDNs) are used to find a server close to the client that can serve these files.
The Django documentation therefore contains articles to deploy static files on a dedicated server and how to configure this server.
The whitenoise package is simply a best effort attempt to serve these files with a Python view. Python is more designed to reduce programmer time, not processing time, so while whitenoise is efficient, very likely it can not compete with CDN.
I am new to the python script. How do you restart a python script with Django through SSH?
I believe that you project is django based.
Django framework has a project directory, where static files are initially placed. And when you run your project for development purposes, django takes all static from the project static directory.
But for the production django deployment usually get runned command manage.py collectstatic to copy all static into another place. And sometimes there are another command - compress. To compress that static.
This is done to make webserver (apache or ngingx) respond static files without asking django process requests like "five me that static file" and gives ability to cache static files. And it speed-up all work.
So, if you serveer is setted up to take static files from static dir (looks like DOMAIN/public/static/main/ is the static dir) it will have no idea about changes in the project dir (looks like DOMAIN/project_book/main/static/main/ is a project dir).
But I agree with #Sause, looks like you have to be very carefull and have exact understanding of what you're doing with killing any process on the production server.
I think it could be useful for you to read Django documentation about static files too. https://docs.djangoproject.com/en/1.9/howto/static-files/
running pkill python in the ssh works.
Coming from an Apache / php world there is something i can't figure out searching for django Development best practices :
With symfony2 framework (or even java Play!) you always have a "public" folder and the webserver only serve files from this folder. Obvious Strategy for security reason it is also clear during dev process to put public files in this folder.
In django it is not clear at all : from my readings it appears as good practice to have a static folder at root level PLUS a Media folder for UGC files and à template folder. No main "public" folder.
Can someone help me to clear my mind here ? Would't it be more secure to have one folder to contain all requests and protect the rest of the app ?
Tanks
There are two different types of 'static' files in django.
Bundled resources/assets with applications (css,javascript typically)
Any files uploaded by your users.
Since these are two different categories of static files, django offers two mechanisms to deal with them. As the first is more common than the second (you may not have an application that requires users to upload files), dealing with the first condition comes built in with django.
As per the standard layout, applications that require static files will include them in a directory called static within the application directory. Django will search for this directory inside any app that is in INSTALLED_APPS for static files. If you have files that are not tied to any app, you can put them in a separate directory. This directory should be added to STATICFILES_DIRS (a tuple) so django is aware of it.
Once you have done this, the collectstatic command will gather all the static files (from the static subdirectories in all applications in INSTALLED_APPS and any directory in STATICFILES_DIRS) and put them in a directory pointed to by STATIC_ROOT; this is so {{ STATIC_URL }} tags work correctly in templates.
Now, all you do is move/point/link the STATIC_ROOT directory so that its accesible from the web. Django expects that all files in STATIC_ROOT are accessible at the root URL that specified by STATIC_URL.
For user uploaded files, django is more hands off. All it really cares about is that you don't put your user uploaded files in the same place as the collectstatic command will be using to read its files - this means, that the MEDIA_ROOT cannot be a directory or subdirectory of STATICFILE_DIRS (if you have specified any directories here, typically this setting is undefined in vanilla django setups).
MEDIA_ROOT is a directory that django can manipulate by creating subdirectories under the root (see the FileField documentation for example).
MEDIA_URL is the URL prefix that points to the root for user-uploaded files. This is so that commands that generate automatic URLs for models work correctly.
As these are two different classes of static files, there are two different types of security and deployment requirements. For example, you might want to store user uploaded files in a S3 bucket but put your application's assets somewhere else.
This is why these two similar things are segregated in django.
You can copy all your static assets into a public/static folder with the command
> python manage.py collectstatic
provided you have set a static path in your manage.py
STATIC_ROOT = "~/mypath/public/static/"
Each app should have its own static assets.
I am reformulating a previous question because I think it was formulated as a Python problem but it is a Django one.
I am installing a project from github called publicmarkup:
The main page displays on the browser but no media (neither js files, nor css files) are read loaded. There is a module called mediasync that seems to be necessary to display correctly the css and the js files of the templates.
I think this a configuration problem. Here's the link settings.py file, Here it could be find the root path of the media folder.
And here's the doc for the mediasync modulet explains how to configure static_url
But I didn't understand anything since I am a newbie to djnago
In Django you have to set up your own workstation serve static files, in both dev and live modes.
You can read about it here.
This explains how to serve static files in your dev environment.
In live mode you serve your static files directly via your end web server, usually either Apache or Nginx.
I am thinking to design my own web app to serve static files. I just don't want to use Amazon services..
So, can anyone tell me how to start the project? I am thinking to develop in Python - Django on Openshift (Redhat's).
This is how ideas are going through in my mind:
A dashboard helps me to add/ delete/ manage static files
To setup API kind of thing (end point: JSON objects) so that I can use this project to serve my web apps!
As openshift uses Apache!, I am thinking to dynamically edit htaccess and serve the files.. but not sure whether it would be possible or not
Or, I can use django's urls.py to serve the files but I don't think djano is actually made for.
Any ideas and suggestion?
How about this:
Use nginx to serve static files
Keep the files in some kind of predefined directory structure, build a django app as the dashbord with the filesystem as the backend. That is, moving, adding or deleting files from the dashboard changed them the filesystem and nginx doesn't have to be aware of this dashboard.
Do not use dynamic routing. Just layout and maintain the proper directory structure using the databoard.
Optionally, keep the directory structure and file metadata in some database server for faster searches and manipulation.
This should result in a very low overhead static file server.