How to set STATIC_URL in Django settings.py for CDN - django

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.

Related

How to write dynamic (Django) URLs for serving images using Whitenoise on Heroku?

I followed this answer here and read the tips here about serving static images. But I'm baffled: The official Whitenoise docs said to write the URLs this way:
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />
And NOT this way:
<!-- DON'T WRITE THIS -->
<img src="/static/images/hi.jpg" alt="Hi!" />
But if I were to use a dynamic URL, such as src="{{recipe.image.url}}", how do I do it?
The first img tag you had is the correct way of pulling static files from your static directory. Whitenoise simply helps serve images/media files on Heroku servers but it isn't needed for local development. To properly use static, however, you need to load static at the top of each template. Example:
<!-- template.html -->
{% extends 'base.html' %}
{% block content %}
{% load static %}
<!-- show static image -->
<img src="{% static 'images/hi.jpg' %}" alt="Hi!" />
<!-- show dynamically -->
<img src="{{ item.image.url }}" alt="{{ item.name }}">
{% endblock %}
Note that the actual path to the image, images/hi.jpg, is in single quotes so as to not conflict with the outside double quotes
I fixed the issue, but I don't understand why. So if anyone can explain it, I'll accept that answer. I have two root folders,static and staticfiles. Each had their own folders images and media. I removed all the existing images, made changes to the code (see below), and re-uploaded the images--and viola! It worked--and worked on Heroku.
STATIC_URL = '/static/' # Didn't work
STATIC_URL = '/staticfiles/' # Yes, worked
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_TMP = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
MEDIA_URL = '/media/' # Didn't work
MEDIA_URL = '/staticfiles/media/' # Yes, worked
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # Didn't work
MEDIA_ROOT = os.path.join(BASE_DIR, 'staticfiles/media/') # Yes, worked

How to connect the css?

How can I plug css into html by importing css from the main folder? I have a network project with 3 app.
network
--chat
--news
--static/style.css
...
My code:
{% load static %}
<link rel="stylesheet" href="{% style.css' %}">
It works if I create a static folder in some app, but I want to put it in the main network folder and then it stops working.
In your settings.py;
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
Then inside your html files;
{% load static %}
<link rel='stylesheet' href="{% static 'styles.css' %}">
Explanation
first of all i am setting the STATIC_URL which helps in the way that everytime you don't need to provide the path of the static files but use the syntax as i used ("{% static 'styles.css' %}").
After that i set the STATICFILES_DIRS which sets the directories where the app should search for the static files which i set to the static folder present in the base directory. You can set it as you want.

Loading static files in template

I am pretty new to Django and I am trying to put static files in my site but I am unable to do so. I am getting 404 when the browser tries to GET my static files
I'm not sure of the best practices or the correct way for Django to find these static files
Here is a picture of my project structure:
Here is my settings.py:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
In my index.html I have a line:
<link href="{{ STATIC_URL }}boothie.css" rel="stylesheet">
<script src="{{ STATIC_URL }}boothie.js"></script>
<script src="{{ STATIC_URL }}jquery.js.1.3.js"></script>
I think this would work:
{% load staticfiles %}
<link href="{% static "css/boothie.css" %}" rel="stylesheet">
<script src="{% static "js/boothie.js" %}"></script>
<script src="{% static "js/jquery.js.1.3.js" %}"></script>
See: Configuring static files
Edit:
You can maintain static files which belong to your home app with the structure like this:
home/
static/
css/
images/
js/
While deploying, you can set STATIC_ROOT to where you want to serve these static files, then run python manage.py collectstatic, django will copy your static files into the STATIC_ROOT directory and you can maintain static files easier (in a single directory) without changing your code.
static_url will give the relative path ....
You may have to include
<link href="{% static "css/boothie.css" %}" rel="stylesheet">

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

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.

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!