Referencing images from template - django

I want to insert an image into my template. The image resides in the same folder as the template.
I tried:
<img src = "imageName.png" />
but for some reason, this wouldn't work.
Does anyone have an idea why that is?

Don't put images in the same folder as templates. Images are a part of static content. You should read about managing static files in django.
Hope that helps.

I'm guessing you're new to the whole django scene, so don't be afraid to hit a few boulders on the way. In fact, this is a problem that I faced too, since I just usually put everything on a web-server, with an index.php file (yes, the horror), and everything was just relative.
So, let me give you a little context, what you are trying to embed on a page is called a static file. What that basically means is a file that does not change, a file that is not dynamic. Now, since these static files require no processing, they are treated specially, and are put inside a static folder. You can see where your static folder is when you check your main settings.py file.
Now often, people make a lot of mistakes with static files, because there are so many variables that have a STATIC infront of them. I know, its totally counter-intuitive, but there are reasons why they're there. So, let me direct you to something that can be a little help in understanding this whole fiasco.
When using static files, you usually use a few special tags. You can learn more about them here. But, I'll just show you how you would embed your image into your html, just as a sample.
{% load staticfiles %}
<img src="{% static "images/myphoto.png" %}"/>
So, how should your directory look like? Well, what you would have is something like this
STATIC_FILES_FOLDER > IMAGES > myphoto.png
Hope that helps.

Related

(Django) How to include template file from app into base.html in templates

I am building a site in Django CMS. In my templates directory for the project is base.html.
I am writing an app "was_this_helpful" to add a dialog box on some pages for users to give feedback. I want to include a file from was_this_helpful/templates into base.html but it says the file does not exist.
{% include 'was_this_helpful/dialog.html' %}
My file structure look like this:
- was_this_helpful
- templates
- was_this_helpful
- dialog2.html
- dialog.html
- required app files
I read somewhere that sometimes template files need to be another level deeper in templates to be found which is why I made the dialog2.html but still it's not working. I do not understand how to accomplish this. Based on what I've read it should work. Is it different because I'm not in another app, just the templates directory?
Without knowing more it's hard to tell if it's a simple solution or not.
The way you have your code written, there is not a was_this_helpful/dialog.html - you only have a dialog2.html inside your was_this_helpful so was_this_helpful/dialog2.html would be the reference path.
I've always created another folder inside my templates folder with the name of the directory above my templates folder. Just like you have with your was_this_helpful second directory. I find that this makes it much easier to extend base.html files.
You can always do it absolutely too by two periods before the path call, so ../was_this_helpful/templates/dialog.html
If you don't have luck with that either, there is an {% extends %} method as well which might accomplish what you're trying to do as well.
Good luck!

Use raw URL or static URL for images?

Is there any difference when using:
<img src="{% static 'images/someimage.png' %}"
and
<img src="https://s3.us-east-2.amazonaws.com/my-bucket/static/images/someimage.png"
The big difference is that in the first method, if you wanted to someday change the location of your static files, i.e. to another directory or even a CDN, you would only need to update the 'static' location in your settings file.
In the second method you would need to do a global search and replace to update the URLs, so some would argue that the first method is preferable.
Other than that, when the site is running, it won't make any difference as far as the user is concerned.
There is no difference as such for the image display.
Only thing is in one you are using relative path and other you are hardcoding image url.
Recommended: Relative path should be used.

django: how to include a static file in a template?

In a Django project, I would like to include a static file in a template. The following is the the project structure:
proj/
main/
static/
main/
js/
main.js
news/
templates/
news/
news.html
In news.html, I would like to include the main.js with the following hypothetical format:
{% load staticfiles %}
...
{% include {% static 'main/js/main.js' %} %}
How do I do it?
The include directive only searches file in template directories. What you could do (although I wouldn't) is to change your settings to also include the static files:
TEMPLATE_DIRS = [
...
"path/to/your/statics",
]
I have a couple of ideas.
The easiest thing to do would be to ensure you have the filesystem loader enabled, and you include the relevant directory containing static files in TEMPLATES[0]['DIRS'] (previously TEMPLATE_DIRS). The caveats are that it will not pick up static files contained inside your installed applications automatically, unless you list them in DIRS, too. Another option would be to use STATIC_ROOT, but that will only work if you run collectstatic every time you change the static file, which you normally don't have to do in development. Another pitfall is that it will only work with local static storage, not if you use any CDN or otherwise host your static files on a different host / network / whatever.
The other thing you can do is to write your own template loader which will use the static files API to load statics as templates. This is a bit more involved, but it should be able to access static files regardless of how they are stored and served.
Should you choose either option, you still have to be careful. For instance, you'll have to ensure that the static files you're including as templates are safe to include into HTML or whatever other context you're using them in. There will be no escaping going on.
In case you're trying to optimize the number of requests the client has to make, there are better ways. You're most likely better off implementing some pipeline that will pre-process and minify your static files. Including any significant chunk of CSS / JS into the HTML will make it impossible for clients to take advantage of caching, forcing them to re-download the same static content over and over again, likely impacting the performance negatively.
Edit: Since you want to just include some dynamic JavaScript variables, that's not a static file at all. What you really want is to create a template containing JavaScript code, and not mess with handling static files as templates. There is no rule that would say every javascript needs to be a static file. If it's dynamic, it's not a static file.
For the record, this was a typical instance of the XY problem. Problem X was dynamically assigning values to JavaScript variables when rendering templates. You came up with including static files in templates as a potential solution, but then got stuck with problem Y, which was that you didn't know how to include static files in templates.

Forcing static files to never cache

I'm serving a Django app on top of Apache, and after my recent deployments, I noticed that a lot of users were being served the new version of the main HTML file, but they were still picking up the older JS files from their Cache.
I tried stuff like patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True), but this doesn't seem to work for static files.
Is there a way to always force every static to be re-fetched from the server when a page is accessed?
You can do a lot of stuff with your headers.
Or you could use something like {% static 'js/jquery.js' %}?v={{ settings.CURRENT_VERSION }}, this way the browser would think that you are using a completely new file, because the name of the file would be something like jquery.js?v=1. I would not really recommend doing this, but it is a really quick hack.

What are the pros and cons in serving CSS and JavaScript using Django template system

Often, I encounter scenarios where I see it makes sense to use template tags in CSS and JavaScript files, such as the use of {{ STATIC_URL }} in CSS to access image. I understand the only way to achieve this is to have CSS and JavaScript files served by Django. I am interested in this approach. But before I commit, I want to hear you experts' experience on it. What are the pros and cons of this approach? Thx.
Pros:
You can make a lot of per-request decisions about how things look and behave.
You can keep the number of different CSS/JS files to a minimum.
Cons:
Browsers tend to cache CSS and JS aggressively, so you'll need to use some aggressive anti-cache techniques. Of course, this means disabling caching for some/all static files.
Every CSS and JS request will consume another thread of your WSGI server. In a normal request/response cycle, each request generally takes up one thread; you're effectively tripling this, at least, so now your app that could handle 200 simultaneous requests now can only handle 66.
When your site makes it big, a CDN probably can't help you.
Alternatives:
Tweak the CSS via javascript, and set a javascript variable inside your page template to control the tweaks.
Use multiple CSS files and control their inclusion dynamically.
Generate static files as needed, but then cache them to disk and serve them via mod_xsendfile. This only works if you are serving static files from somewhere the django process can write to, such as on the same machine or a network mount.
Personally, I've been sticking with the Django team's advice to make CSS and JavaScript static files, served directly by the server instead of via Django. It hasn't been a problem and has simplified a lot of things. Generally, any time I think I need a dynamioc CSS or JS file, there's a way to refactor so I don't.
For example:
the use of {{ STATIC_URL }} in CSS to access image
I'm not sure how variable your {{ STATIC_URL }} is, but I've found that using the <base> tag in my pages fixes a lot of things. I assume this is for background images? Could you update your question to give an example?
Another thing I've done is, if my JavaScript needs dynamic data, I'll put most of the code in a JavaScript library I serve as a static file and then put the minimum dynamic stuff in a <script> tag at the end of the page. Usually I'll put it all in an object (looking a lot like JSON) and then just pass that object to a function. Come to think of it, you could just take all the dynamic stuff, make a dictionary out of it in your view function, encode it into JSON, and pass it via context. Then your page template just looks something like:
<html><head>
...
<script src="{{ STATIC_URL }}/js/foo.js"></script>
...
</head><body>
...
<script>
foo_main({{ foo_params_json|safe }});
</script>
</body></html>
This makes it a lot easier to reuse this code.