How to use images loaded with webpack in django templates? - django

I am using Webpack 2 and use url-loader to load all of my images. before using webpack, I used the static template tag like this:
<img src="{% static "img.png" %}" ... />
and now webpack renames all of the images to some hash and ext like this:
img.png becomes img-[somehash].png. (I use this for cache invalidation).
the problem is how to load the new image (with the hash) in django templates ?!
thanks in advance.

How about passing correct path in context data? In Django view you are passing context data to the template. You can use regular expressions to find the name of file with hash. Let say that your images are in the directory which variable called STATIC_ROOT links to (place where all static files are). First, you need to find files:
from yourproject.SETTINGS import STATIC_ROOT
all_files = os.listdir(STATIC_ROOT)
Let say that name of the file you want is picture.png, and it was changed to picture-asd12edaq.png Then, find correct file name using regex or simple in operator:
for file in all_files:
if 'picture' in file and '.png' in file:
context['src'] = file
break
Then in template use simple <img src="{% static {{src}} %}" ... />

Related

How can I apply bootstrap to my whole django project?

I've been looking at a few guides on applying bootsrap to django, and I am as far as having a static file in the root of my site, containing the css and js files within bootstrap, but when it comes to linking the files I am having an issue.
So I am trying to link the stylesheet inside of my base.html file but am not sure how to format it as for some reason using {% %} inside of the href field is being interpreted as part of the directory. In one of the videos I have watched he links it like thisBut I'm not really sure how to interpret this as trying to apply it to my own like so
href = "{% static 'artForAll/css/bootstrap.css' %}"
With the file structure for reference:
\AFA\src\artForAll\static\artForAll\css
I am given an error about a non existent file as it is taking the {%%} as part of the directory
My settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,"static"),
]
File structure(blue highlighted file is where BASE_DIR leads:

Serving static images on django application?

I am have been having troubles figuring out how to serve static images with my django application. However, I have figured out a sort of "hack" to get it working but it doesn't allow for much flexibility.
In the html files I have tried the following...
<img src="{{ STATIC_URL }}textchange/nextarrow.png" class="foobar" id="foobar">
Above: The pages will load when I use this but the images will not work.
<img src="{% static "textchange/nextarrow.png" %}" class="foobar" id="foobar">
Above: The pages will not load, I get a server error
<img src="thefullurltoS3bucket/nextarrow.png" class="foobar" id="foobar">
Above: The images will load fine
I have been trying all these different formats when going to production with Heroku and S3. The question I have is is the way I'm serving my static images correct? I use the last example in which I make the src the full url to the bucket at s3. Is that fine?
It should be noted that when I use the static tag serving css files works fine. Images is the only problem.
Your first and second solutions ( that you got server error and not loading ) is the correct way of using static files which is:
<img src="{% static "textchange/nextarrow.png" %}" class="foobar" id="foobar">
review your settings.py file and set STATIC_URL and STATIC_DIRS and also STATIC_ROOT, if you got server error maybe you set the STATIC_URL or STATIC_DIRS wrong. you can find plenty of posts about these settings.
Also check your image url in browser ( sth like 127.0.0.1:8000/static/files/etc.jpg )see if you can access the image.
Serving static files in Django can be a pain.
First, make sure you use the static template tag correctly in your template:
{% load static from staticfiles %}
<img src="{% static 'path/to/image.jpg' %}">
In your settings, have your STATIC_URL point to something like '/static/', your STATIC_ROOT point to the directory where you'll actually serve your files post-collectstatic, and your STATIC_DIRS to where you'll place your static files within your project (i.e. 'static' directory).
If you're serving from S3, you'll probably follow a tutorial like this one.

Static URL in JavaScript

I have a CSS file which is being used in my template file
<link href="{% static "assets/style/reset.css" %}" rel="stylesheet" type="text/css"/>
I want to access the 'static' in my JavaScript. Is it possible? How can I do it?
Your javascript has to pass through django's template redering. You could do this by rendering your javacript inside of your template like Django Template Variables and Javascript suggests.
Or you could create a view that just renders your javascript dynamically:
(r'^dynamic.js$', dynamic_js)
def dynamic_js(request):
"""
Create a js file dynamically
"""
return render(request, 'dynamic.js',
content_type='application/javascript')
# dynamic.js
# can use template tags now!
Having django serve your static assests is extremely inneffiecient, and is one of the first things to migrate away from if you want a speedy site. If your js file is rarely changing it might be better to create some sort of build process where you can generate your dynamic js with django (so you can use the template variables) and save it to you static folder, so that your webserver can serve the content for you!

Using Django urls in javascript files

I am trying to use url-names in my javascript/jquery files for AJAX requests and I have found several solutions that can solve this problem. The one that I am currently using is the following.
I define a url to serve javascript files:
urls.py
url(r'^js/([\w\.\-]+)/([\w\.\-]+)/$', 'views.get_javascript_file', name='get_javascript_file')
url(r'^getmoredicus/$', 'load_discussions', name="load-discus"),
Then I define the view that renders the javascript files.
views.py:
def get_javascript_file(request, app_name, js_file):
'''
Used to request and serve rendered javascript/jquery files.
'''
return render_to_response("%s/%s.js" % (app_name, js_file),
context_instance=RequestContext(request))
Now in the html files, we can use the get_javascript_file url to get the rendered javascript files.
html files:
<script type="text/javascript" src="{% url get_javascript_file 'myapp' 'jsfile' %}"></script>
Now in any javascript file, I can access the url-names through {% url url-name %}.
Questions:
1) Is there a better/faster way to use url-names in javascript files? I know that there are some apps already created to accomplish this but I want to get everyone's(django experts) opinion on the best way to accomplish this.
2) Can we cache the rendered javascript files after they have been rendered the first time so that in each subsequent request, we don't have to render them again? If yes, then how can we go about doing that.
3) In this method, we are rendering the script files from their apps folders. Is there a way to access the static files located in STATIC_ROOT from the get_javascript_file view? I am just thinking about how this would work in a production environment. Is it a good practice to access static files from their apps folders rather than putting them in STATIC_URL and accessing them from there?
NOTE
I know that there are already some questions on SO that answer some parts of this question, but I just wanted to get to the bottom of this once and for all for future django learners. What is the best way to use url-names in javascript or any script for that matter?
I'm not a fan of running external js through the view rendering. Especially if you're using something like django-compressor to compress and cache your js files.
I prefer to just include the variables in a script tag prior to including the external files.
<script>
my_var = "{{ MY_PROPERTY }}"
</script>
<script type="text/javascript" src="{{ STATIC_URL }}js/external_script.js"></script>
That solution is also not always ideal, but I'm open to other solutions.

Cannot get images to display in Django(1.3) project

I'm making a simple Django project but I cannot get any images to display in my pages.
Django documentation at https://docs.djangoproject.com/en/1.3/howto/static-files/#basic-usage states
Basic usage Put your static files somewhere that staticfiles will find
them.
By default, this means within static/ subdirectories of apps in your
INSTALLED_APPS.
Your project will probably also have static assets that aren’t tied to
a particular app. The STATICFILES_DIRS setting is a tuple of
filesystem directories to check when loading static files. It’s a
search path that is by default empty. See the STATICFILES_DIRS docs
how to extend this list of additional paths.
Additionally, see the documentation for the STATICFILES_FINDERS
setting for details on how staticfiles finds your files.
Make sure that django.contrib.staticfiles is included in your
INSTALLED_APPS.
For local development, if you are using runserver or adding
staticfiles_urlpatterns to your URLconf, you’re done with the setup –
your static files will automatically be served at the default (for
newly created projects) STATIC_URL of /static/.
You’ll probably need to refer to these files in your templates. The
easiest method is to use the included context processor which allows
template code like:
See Referring to
static files in templates for more details, including an alternate
method using a template tag.
So I did this in settings.py:
STATICFILES_DIRS = (
'/home/abc/django/project1/media/',
)
and enabled 'django.contrib.staticfiles',
In media, I have a folder img, which has various jpg files.
In my template, I have this as one of the lines:
<img src="{{STATIC_URL}}img/{{var}}.jpg">
When I'm passing var to this template via my view.
The HTML page seems to render this tag as "<img src="img/abc.jpg"> where var="abc".
But my browser refuses to display the image. What have I done wrong?
Did you see ths part in the documentation:
If {{ STATIC_URL }} isn't working in your template, you're probably not using RequestContext when rendering the template.
Do you also use RequestContext in your view to render the template?
Here is an alternative approach:
settings.py:
import os
PROJECT_DIR = os.path.dirname(__file__) + '/../'
STATIC_ROOT = os.path.join(PROJECT_DIR, 'media/')
STATIC_URL = '/media/'
In your template:
{% load staticfiles %}
<img src="{% static img/foo.jpg %}" />
If you need to pass a variable, use the prefix method:
{% load staticfiles %}
<img src="{% get_static_prefix %}img/{{var}}.jpg" />