So I'm trying to run multiple instances of Django on a server for now, one under /dev/, one under /test/, etc..
The web server is setting the correct SCRIPT_NAME setting and I can serve pages, templates, the whole admin panel fine, except for static assets. Static assets are served by Django using WhiteNoise.
The application is supposed to use the value of SCRIPT_NAME as the static URL, ie all static assets are served from the application root.
So far I've tried the following settings against the admin panel:
# SCRIPT_NAME = '/dev/' Set in env
# URL for static assets should be `/dev/`
STATIC_URL = '/' # Browser looks for static assets in `/`, drops script_name
STATIC_URL = None # Browser looks for static assets in `/`, drops script_name
STATIC_URL = `/dev/` # Browser looks for static assets in '/dev/dev/`
I'm wondering if I'm missing a setting here or if the problem might be elsewhere. Going by the docs I understand that STATIC_URL = '/' should work?
Finally got a working config for running my app under /dev/:
# SCRIPT_NAME = '/dev/' set from uwsgi, or use FORCE_SCRIPT_NAME
STATIC_URL = '/dev/'
WHITENOISE_STATIC_PREFIX = '/'
This seems to correctly prepend /dev/ to all static URLs, and makes whitenoise serve static assets from that directory (no subdir).
Not sure if this is the correct approach though?
Thanks #Geotob. this saved me after so many hours of research. As per docs WhiteNoise 6.2 is supposed to handle this automatically. but some how its not working
http://whitenoise.evans.io/en/stable/django.html?highlight=WHITENOISE_STATIC_PREFIX#WHITENOISE_STATIC_PREFIX
I was hit with this issue when i tried to deploy django with nuxt frontend on Digital Ocean's app platform offering. where my django-drf was running on /api. the admin page wouldn't load with static files on /api/admin/....
finally this setting is working for me. below is my snippet if anyone stumbles upon similar situation.
app_route = os.getenv("APP_PLAT_ROUTE", None)
if app_route is not None:
rel_app_route = os.path.relpath(app_route, '/')
FORCE_SCRIPT_NAME = "/{0}".format(rel_app_route)
WHITENOISE_STATIC_PREFIX = '/static/'
STATIC_URL = "/{0}/static/".format(rel_app_route)
Related
I have a problem about serving admin uploaded files in my templates.
I set:
MEDIA_URL='/media/'
MEDIA_ROOT = 'assets/'
and my models are like:
mainPhoto = models.ImageField(upload_to="articles/")
When in my templates, I try:
<img src="{{MEDIA_URL}}{{article.mainPhoto}}" />
The image doesn't show up on the website.
I found one deprecated solution with the django .serve(), but I hope to avoid using it.
I was looking everywhere and didn't find any answer, so I hope someone here will be able to help me.
There are two parts to make this work. First is the Django configuration. There are really two settings for this which you have already mentioned - MEDIA_URL and MEDIA_ROOT. As already noted in the comments the MEDIA_ROOT has to be an absolute path. For example:
MEDIA_ROOT = `/abs/path/to/project/media/`
Second part is actually serving the files. If you are in production, you NEVER want to serve your static or media files through Django so you should configure Apache or nginx or whatever server system you are using to serve the files instead of Django. If you are on the other hand still developing the app, there is a simple way to make Django serve media files. The idea is to modify your urls.py and use the Django's static files server to serve media files as well:
# urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# other patterns
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
More about this approach at Django docs.
Also FYI, you probably should not use {{MEDIA_URL}}{{article.mainPhoto}} to get the url of an image. This approach will break for example if you will no longer use file system storage for static files and will switch to something different like Amazon S3. It is always a good idea for the storage backend to figure out the url:
<img src="{{article.mainPhoto.url}}" />
I've looked through countless answers and questions trying to find a single definitive guide or way to do this, but it seems that everyone has a different way. Can someone please just explain to me how to serve static files in templates?
Assuming I've just created a brand new project with Django 1.4, what all do I need to do to be able to render images? Where should I put the media and static folders?
Put your static files into <app>/static or add an absolute path to STATICFILES_DIRS
Configure your web server (you should not serve static files with Django) to serve files in STATIC_ROOT
Point STATIC_URL to the base URL the web server serves
Run ./manage.py collectstatic
Be sure to use RequestContext in your render calls and {{ STATIC_URL }} to prefix paths
Coffee and pat yourself on the back
A little bit more about running a web server in front of Django. Django is practically an application server. It has not been designed to be any good in serving static files. That is why it actively refuses to do that when DEBUG=False. Also, the Django development server should not be used for production. This means that there should be something in front of Django at all times. It may be a WSGI server such as gunicorn or a 'real' web server such as nginx or Apache.
If you are running a reverse proxy (such as nginx or Apache) you can bind /static to a path in the filesystem and the rest of the traffic to pass through to Django. That means your STATIC_URL can be a relative path. Otherwise you will need to use an absolute URL.
The created project should have a static folder. Put all resources (images, ...) in there.
Then, in your HTML template, you can reference STATIC_ROOT and add the resource path (relative to the static folder)
Here is the official documentation:
How to manage static files: https://docs.djangoproject.com/en/1.4/howto/static-files/
Static Files in general: https://docs.djangoproject.com/en/1.4/ref/contrib/staticfiles/
If you are planning to to deploy in a production type setting then you should read the section here: https://docs.djangoproject.com/en/1.4/howto/static-files/#staticfiles-production
Generally you put our static and media folders outside of the django project app
Define your STATICFILES_DIRS, STATIC, and MEDIA path in the settings.
Create staticfiles folder beside your templates folder, urls.py, settings.py, etc...
You don't have to create media folder because it will automatically created when you upload images.
In your urlconf put this one:
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.static import static
admin.autodiscover()
urlpatterns = patterns('',
.............
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()
In templates:
{% load static %}
<img src="{% static 'images.png' %}">
<img src="{{MEDIA_URL}}images.png">
Like the 1 billionth static file question about Django 1.3. I've been searching and trying so many things but nothing seems to work for me. Any help would be appreciated. Will try and give as much information as possible.
URL FILE
urlpatterns = patterns('',
url(r'^projectm/statictest/$','project_management.views.statictest'),)
VIEW
def statictest(request):
return render_to_response('statictest.html',locals())
TEMPLATE
<html><head><title>Static Load Test Page</title></head>
<body>
{% load static %}
<img src="{{ STATIC_URL }}testimage.jpg" />
</body></html>
SETTINGS
STATIC_ROOT = '/home/baz/framework/mysite/static/'
STATIC_URL = '/static/'
STATICFILES_DIRS = ('',)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
TEMPLATE_DIRS = (
"/home/baz/framework/mysite/templates"
FILES
-bash-3.2$ pwd
/home/baz/framework/mysite/templates
statictest.html
-bash-3.2$ pwd
/home/baz/framework/mysite/project_management/static
-bash-3.2$ ls
testimage.jpg
Not too sure if there is any other information that would be helpful. But basically when I go to this test page and check the page source, the url is pointing to
<img src="/static/testimage.jpg" />
However the image does not load. I have tried this on multiple browsers too. Maybe I am missing an imort statement somewhere?
cheers for the help
Are you using the built in runserver command or do you serve the Django app some other way?
If you use runserver then your problem is that you don't tell Django where to find your static assets in the filesystem. You need to set STATIC_ROOT to a filesystem path where your static assets can be found. Try setting it to: /home/baz/framework/mysite/project_management/static/
If you are using a different server (like gunicorn behind Nginx for example) then it is the responsibility of the front-end server to intercept requests for /static/ and serve them for you.
Also remember to run the ‘collectstatic’ management command once you have set ‘STATIC_ROOT’.
https://docs.djangoproject.com/en/1.4/howto/static-files/#deploying-static-files-in-a-nutshell
Just for some context, I am testing running a Django (1.4) app behind nginx+gunicorn on webfaction in order to run the admin parts securely. This is working fine. The nginx proxy is redirecting requests from http://domain.com/admin to https://domain.com/admin and Django is serving everything up without issue. The greater issue is the static files. I have these being served up from a separate static directory that is accessed both via http and https. My problem is how to render the static urls in my app's templates as well as the admin interface templates in such a way that the appropriate prefix is applied (http or https) depending on whether the request is secured or not.
For my app's templates, I've used the {{ STATIC_URL }}path/to/resource convention, which allows me to easily adjust the STATIC_URL context variable in a template_context_processor function. But this doesn't have any effect on the administrative templates which use the {% static path/to/resource %} templatetag to render the url.
The best I have come up with is to make two url options in settings.py:
STATIC_URL = 'https://mydomain.com/static/'
NON_SECURED_STATIC_URL = 'http://mydomain.com/static/'
Then added the following function to TEMPLATE_CONTEXT_PROCESSORS:
def set_static_url(request):
if not request.is_secure():
return { 'STATIC_URL': settings.NON_SECURED_STATIC_URL }
This is actually working, but it seems rather hackish. I'm also quite new to Django and I feel there must be a better or more appropriate way of doing this.
I'm moving over my django app to Heroku, and I was wondering what the proper way to handle static files is. Do I just push them via git to Heroku? Or should I be storing them on SW3 or something? Also, what should the STATIC_ROOT and such be?
Thanks!
You should store them externally on a service like S3 - while Heroku can serve static files, it's not designed to.
Here's a good primer on getting started with S3:
https://devcenter.heroku.com/articles/s3
Use django-storages http://django-storages.readthedocs.org/en/latest/index.html to collect static files to your S3 bucket and serve them accordingly.
These are the necessary settings you'll need to have for S3:
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
AWS_ACCESS_KEY_ID = 'access-id'
AWS_SECRET_ACCESS_KEY = 'secret-key'
AWS_STORAGE_BUCKET_NAME = 'bucket-name'
AWS_PRELOAD_METADATA = True # necessary to fix manage.py collectstatic command to only upload changed files instead of all files
MEDIA_ROOT and STATIC_ROOT are superceded by DEFAULT_FILE_STORAGE and STATICFILES_STORAGE respectively and hence not needed. You will, however, want to set MEDIA_URL and STATIC_URL to something like
STATIC_URL = 'https://bucket-name.s3.amazonaws.com/static/'
ADMIN_MEDIA_PREFIX = 'https://bucket-name.s3.amazonaws.com/static/admin/'
If you want to store your static and media files in different subfolders, this is a great solution: https://stackoverflow.com/a/10825691/674794
You'll want to set MEDIA_URL and STATIC_URL to the respective new folders, e.g.
MEDIA_URL = 'https://bucket-name.s3.amazonaws.com/media/'
STATIC_URL = 'https://bucket-name.s3.amazonaws.com/static/'
You'll also want to manually execute manage.py collectstatic and disable Heroku's automatic collectstatic as per https://devcenter.heroku.com/articles/django-assets#disabling_collectstatic, as Heroku's collectstatic will reupload every static file to S3 every time you push even if the files haven't been modified, adding a hefty transfer and request load to S3 and slowing down your pushes.
Then just continue using {{ STATIC_URL }} in your templates like usual and you should be set!
<link href='{{ STATIC_URL }}css/styles.css' type='text/css' rel='stylesheet'>
If you want to start off simple and choose not to immediately take that route though, you can do the quick hack in your urls configuration by following Cesar's mentioned post at Heroku - Handling static files in Django app, though there'll be a significant decrease in app performance.
While #Intenex's answer might still be the way to go if you have a lot of static content, for getting started, Heroku suggests using Whitenoise.
Here's Heroku's article aptly entitled "Django and Static Assets".
And the whitenoise documentation itself has a nice section on "Shouldn’t I be pushing my static files to S3 using something like Django-Storages?"