How can I get the MEDIA_URL from within a Django template? - django

I'm somewhat confused as to how Django operates with static content. Essentially, in the settings.py file, we define MEDIA_URL which points to the URL to use when resolving static media such as scripts and styles, as well as MEDIA_ROOT, a reference to where things live on the filesystem.
However, it doesn't seem clear how I can get access to MEDIA_URL from a template, and it's kind-of-important if I want to use Django's mechanism for loading static content at all. Essentially, I have my base template looking somewhat like this:
<html>
<head>
{% block styles %}
<link rel="stylesheet" href="{{ MEDIA_URL }}styles/master.css"/>
{% endblock %}
<title>{% block title %}Page Title{% endblock %}</title>
</head>
<body>
{% block scripts %}
<script type="text/javascript" src="{{ MEDIA_URL }}scripts/jquery.js"></script>
{% endblock %}
</body>
</html>
Will the above code actually work? I've heard that you have to use other plugins to get something like this up and running, which seems kind of strange, as presumably the whole point behind defining MEDIA_URL is to use it in templates.

To access STATIC_URL in your templates, make sure django.core.context_processors.static is in TEMPLATE_CONTEXT_PROCESSORS, and that you're using a RequestContext. More details here.
In addition, static files should be placed under STATIC_URL, not MEDIA_URL, unless it is user-uploaded content.

I would say that you dont have to use MEDIA_URL and MEDIA_ROOT for your Js,css,img files!
I use STATIC_ROOT,STATIC_URL instead! as far as I know MEDIA_* is for upload of files, such as images, or any document!
Also I use STATIC_* because in my case, I have my js,css,... files in a S3 storage! so when I run collectstatic it just copy all my STATIC files to my cloud storage! So in my templates I have something like this:
{% block js %}
<script src="{{ STATIC_URL }}js/libs/modernizr-2.0.min.js"></script>
<script src="{{ STATIC_URL }}js/libs/respond.min.js"></script>
{% endblock %}
Check it out this note from Django docs:
Note In previous versions of Django, it was common to place static
assets in MEDIA_ROOT along with user-uploaded files, and serve them
both at MEDIA_URL. Part of the purpose of introducing the staticfiles
app is to make it easier to keep static files separate from
user-uploaded files.
For this reason, you need to make your MEDIA_ROOT and MEDIA_URL
different from your STATIC_ROOT and STATIC_URL. You will need to
arrange for serving of files in MEDIA_ROOT yourself; staticfiles does
not deal with user-uploaded files at all. You can, however, use
django.views.static.serve() view for serving MEDIA_ROOT in
development; see Serving other directories.

Related

How to correctly include SVG sprite sheets in Django templates

I created an SVG sprite sheet and am now looking at various ways of using it in my Django templates.
The easiest way is:
Add the spritesheet in the templates/ folder (e.g. templates/svg_spritesheet.svg)
Include it in the Django template like so: {% include "svg_spritesheet.svg" %}
Call upon a given svg in the HTML code via: <svg><use xlink:href="#my_svg"></use></svg>
This has worked for me. But this method has operational imperfections.
For example: I normally park my static assets at {{ STATIC_URL }}. That is better for organization purposes. Secondly, I employ webserver level caching for assets in {{ STATIC_URL }}. I do not employ such caching for my /templates folder however.
So naturally, it seems to me that it would be better if I parked my SVG spritesheets at {{ STATIC_URL }}. But once I do that, how do I include it in my Django template?
None of the following methods work:
{% include 'static/svg_spritesheet.svg' %}
{% include '{{ STATIC_URL }}svg_spritesheet.svg' %}
<object type="image/svg+xml" data="{{ STATIC_URL }}svg_spritesheet.svg"></object>
<link type="image/svg+xml" href="{{ STATIC_URL }}svg_spritesheet.svg">
Can an expert give an illustrative example of how to use SVG sprite sheets that are placed at {{ STATIC_URL }}? Thanks in advance (in case warranted, I'm using Django 1.8.19 for the project in question).
Note: in case you miss it - this question deals with SVG sprite sheets, not individual SVGs. A single sprite sheet contains multiple SVG images - which can be selectively called as (and when) required.
The answer was right under my nose.
Simply insert the required location when rendering an SVG from the spritesheet:
{% load static %}
<svg>
<use
href="{% static "svg_spritesheet.svg" %}#my_image"
>
</use>
</svg>
This way, you can keep your SVG spritesheets in the static folder - so all/any caching infrastructure fully applies. Happy coding!
I'm not sure I understood your question, but in Django, the correct way to load static files is by using the staic tag.
Below I show a basic example:
template.html
{% load static %}
<img src="{% static "svg_spritesheet.svg" %}" alt="My svg">
In this way, Django is responsible for managing the url and serve the svg, by using the corresponding storage StaticFilesStorage, which is not called if you generate the url manually
{{ STATIC_URL }} did not work for me, so I amended it to
<svg><use xlink:href="{% static 'svg_spritesheet.svg' %}#my_image"></use></svg>

How to set STATIC_URL in Django settings.py for CDN

I want to use static file in my django 2.0.5 template that is located on:
https://my_cloud_front_adress.cloudfront.net/staticfiles/picture_small.jpg
On Heroku i've set varible:
STATIC_URL = https://my_cloud_front_adress.cloudfront.net/staticfiles/
templates/base.html
{% load static %}
{# this one is NOT working #}
<img src="{% static 'picture_small.jpg' %}" alt="my test image"/>
{# this one is working #}
<img src="https://my_cloud_front_adress.cloudfront.net/staticfiles/picture_small.jpg" alt="my test image"/>
How should i set STATIC_URL to make this work in the template:
<img src="{% static 'picture_small.jpg' %}" alt="my test image"/>
As per django documentation you need to..,
django.contrib.staticfiles add this to INSTALLED_APPS.
add STATIC_URL = '/static/' to your settings.py (I think you forgot to add this.)
Add {% load static %} at the top of your template.
Then use <img src="{% static "my_app/example.jpg" %}" alt="My image"/>
In addition you also need to add STATICFILES_DIRS
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
The STATIC_URL value you give will be relative to your app, so adding an external url there doesn't make sense. If you want the files to be locally sourced, you should download them and store them locally in your app in a directory specified in STATICFILES_DIRS, and configure your static files as described in the Django docs.
Otherwise, you can just access the files directly by the url, without trying to treat them as static files in your project.
user3170828 answer is correct, but to add you can try with django-storages, which will take care of syncing static files to S3/Cloudfront and URL.

Appropriate way to handle deprecated `adminmedia` templatetag and {% admin_media_prefix %}

From django 1.5 onwards, https://docs.djangoproject.com/en/1.5/releases/1.5/#miscellaneous
The template tags library adminmedia, which only contained the
deprecated template tag {% admin_media_prefix %}, was removed.
Attempting to load it with {% load adminmedia %} will fail. If your
templates still contain that line you must remove it.
So what is the appropriate way to replace code found in legacy libraries and my legacy projects which still uses {% load adminmedia %} and loads css like:-
<link rel="stylesheet" type="text/css" href="{% load adminmedia %}{% admin_media_prefix %}css/login.css">
?
Since Django 1.3 you can use django.contrib.staticfiles app.
Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS and the STATIC_ROOT and STATIC_URL options are specified in your settings.py.
Then run manage.py collectstatic command and all applications' static files will be collected in STATIC_ROOT folder.
In the templates you can use the {{ STATIC_URL }} context variable (make sure that django.core.context_processors.static is included in TEMPLATE_CONTEXT_PROCESSORS) or the {% static %} template tag.
<link href="{{ STATIC_URL }}admin/css/login.css" rel="stylesheet">
or
{% load staticfiles %}
<link href="{% static 'admin/css/login.css' %}" rel="stylesheet">
I just copied what's in base.css:
{% load admin_static %}
and then
<link href="{% static 'admin/css/base.css' %}" rel="stylesheet">
(replace base.css with whatever you need, like login.css in your case)
Make sure you have django.contrib.staticfiles in your INSTALLED_APPS.
(I didn't need to configure STATIC_ROOT and run manage.py collectstatic as suggested previously by Anton)

STATIC_URL not working

I am struggling to pull media out for my templates using the STATIC_URL variable. For example I have this code
{% extends "admin/change_list.html" %}
{% load i18n %}
{% block extrahead %}
<!--[if IE]>
<script type="text/javascript" src="{% firstof STATIC_URL MEDIA_URL %}django_qbe/js/excanvas.js"></script>
<![endif]-->
<script type="text/javascript" src="{% firstof STATIC_URL MEDIA_URL %}django_qbe/js/jquery.js"></script>
Each time the template loads it tries to pull off the MEDIA_URL. If I change it to
{% extends "admin/change_list.html" %}
{% load i18n %}
{% load static %}
{% block extrahead %}
<!--[if IE]>
<script type="text/javascript" src="{% get_static_prefix %}django_qbe/js/excanvas.js"></script>
<![endif]-->
<script type="text/javascript" src="{% get_static_prefix %}django_qbe/js/jquery.js"></script>
My question is why doesn't my first version of this template work?
There is a static context-processor (Version 1.8), which isn't the same as the media one. You need to make sure you have django.core.context_processors.static in your context-processor list, so it can add STATIC_URL to the context.
As commented, for Django 3.0, that is now at django.core.context_processors.static. Django sure has changed a lot since 2011...
From the docs:
If {{ STATIC_URL }} isn't working in your template, you're probably not using RequestContext when rendering the template.
https://docs.djangoproject.com/en/dev/howto/static-files/
Most things have already been mentioned but to compile and add a little:
Make sure your settings.py file correctly specifies the locations of your static files. As Steven Keith wrote, you should have something like:
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = ''
STATIC_URL = '/static/'
ADMIN_MEDIA_PREFIX = '/static/admin/'
import os
# Additional locations of static files
STATICFILES_DIRS = (
os.path.join(os.path.dirname(__file__), 'static'),
)
Then make sure that your TEMPLATE_CONTEXT_PROCESSORS include 'django.core.context_processors.static'. If there's no entry for TEMPLATE_CONTEXT_PROCESSORS in your settings.py, then it defaults to the below, and you're all good.
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
)
Make sure that you use RequestContext when you render your templates. django.shortcuts.render does this by default (see here), so you could just call
from django.shortcuts import render
def myViewFunction(request):
return render(request, 'myTemplate.html')
Be careful as django.shortcuts.render_to_response doesn't do this for you unless you add an argument, so you'd have to write something like
from django.shortcuts import render_to_response
def myViewFunction(request):
return render_to_response('myTemplate.html', myContext, context_instance=RequestContext(request))
For me, the answer was simply to stop using STATIC_URL, and instead use the following:
I changed mine from
<link href="{{ STATIC_URL }}css/survey.less" media="screen" rel="stylesheet" type="text/css"/>
to:
<link href="{% static "css/style.less" %}" media="screen" rel="stylesheet" type="text/less"/>
And now it works fine. Much simpler, and I suspect this is also the slightly "more correct" way to use static now (as of Django 1.4) anyways. Please see the Django docs for more info on the specifics.
Dont forget to add {% load static from staticfiles %} at the top of your templates that use it too.
As I've been accused of not answering the question, let me clarify me thought process:
My question is why doesn't my first version of this template work?
STATIC_URL is returning a False value
To determine why, here is the steps I would use:
Try printing it in your templates body - {{ STATIC_URL }}.
Check settings.py to ensure the value is set - STATIC_URL = '/static/'
Check whether you have the STATIC files set up properly in runserver:
https://docs.djangoproject.com/en/1.3/ref/contrib/staticfiles/
For reference I use:
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = ''
STATIC_URL = '/static/'
ADMIN_MEDIA_PREFIX = '/static/admin/'
# Additional locations of static files
STATICFILES_DIRS = (
os.path.join(PROJECT_DIR, 'static'),
)
or an Apache alias:
Alias /static /Users/stevenkeith/foo/bar/static
<Directory /Users/stevenkeith/foo/bar/static>
Order deny,allow
Allow from all
</Directory>
or whatever method you want, nginx, etc
Here is a tutorial to implement load the static image
tree
setting.py
base.html
What worked for me was pointing the STATIC_ROOT and the STATIC_URL to the same static directory
my basic file structure
core/static/(
...
img/logos/green.jpg
js
css
...
)
...
STATIC_ROOT='/core/static/'
STATIC_URL='/core/static/'
and so in my html template I did
{% load static %}
<img src="{% static 'img/logos/green.jpg' %} />"
...
It worked!

including css in Django

I'm new to Django, and i'm having hard time including css styles in a template.
I read this and tried to do the same but it's not working for me.
my Template:
{% load static %}<html><head><link href="{% get_static_prefix %}/style.css" rel='stylesheet' type='text/css' /></head><body>
the HTML i get:
<head><link href="C:/Users/Nayish/workspace/am/src/am/static/style.css"rel='stylesheet'type='text/css' /></head>
Note that this is the folder containing my css.
Thanks, Boris.
Make sure you haven't mixed up the STATIC_ROOT and STATIC_URL settings.
STATIC_ROOT defines where the files are on the storage system (usually your local hard disc for local development), while STATIC_URL defines the URL from where the server serves them. The second one is usually referred to in templates, and it is also the value that the {% get_static_prefix %} template tag returns.
I am guessing you aren't using static css sheets. I always just do:
<html>
<head>
{%block stylesheet %}
<style type="text/css" title="currentStyle">
#import "{{MEDIA_URL}}css/style.css";
</style>
{% endblock stylesheet%}
....
I then set my Media root, and store the files as
MEDIA_ROOT=<fullyquallified patyh>/Media/css/<css files>
MEDIA_URL=http://localhost/mysite/
It should be noted that STATIC_URL defaults to MEDIA_URL if its not defined.