Displaying an image with an absolute path on server - django

Suppose I have an image on the server machine (Django on Windows) at C:/myimage.jpg. I want to display this image on the client machine. The image path is passed to a template as a context variable image_path. It is important that the path is absolute and not relative. Here is my attempt on the template:
<img src="{{ image_path }}" />
However, the client does not see an image at all. My first guess is that when it reads image_path, it actually reads C:/myimage.jpg, and therefore looks on the client machine, rather than the server. How can I make it look for the image on the server instead?

Using absolute paths for static content within the app is not a correct idea. You should use images using the following method,
add this in your settings.py
STATIC_URL = '/static/'
and then accessing the image using
{% load staticfiles %}
<img src="{% static "my_app/myexample.jpg" %}" alt="My image"/>
please read the guidelines for more details

Even if you could tell a browser to look in a specific file location on the server, how could that ever be a good idea? What if the user entered the path to the settings.py file containing your database credentials?
Clearly, you can only look for files via URLs, and those URLs actually have to be mapped to actual files by the server. So you need to configure your web server in such a way that it maps a URL to the place your files are, and then you can use that URL in your template.

Related

How to rename "admin" static files in Django?

When loading up the Django admin pages, you load in the default Django admin css / js files. For example, example.com/staticfiles/admin/css/base.css.
I've enabled a default Amazon WAF (firewall) rule that blocks all access to pages that have the word "admin" in their URL. This has been great so far -- as most bots love looking for /admin domains.
However, this ends up blocking the Django admin. I'm able to rename the Django admin url to /manager using one line of code in urls.py, however I can't figure out how to to change the admin static files' filepath. I'm currently getting raw, unstyled HTML in my admin as all the static files are blocked.
Ideally, in settings.py I could write:
ADMIN_FOLDER_NAME = 'manager'
and then
example.com/staticfiles/admin/css/base.css would get rewritten to example.com/staticfiles/manager/css/base.css.
How can I tell Django to look in a different folder for admin files?
Note
I am not asking how to rename the url for accessing the admin page. I am talking about the admin static files. The below code does change the admin page url, but does not change the url for the staticfiles.
urlpatterns += [url(r'^newadminurl', admin.site.urls)]
As you may have noticed in example.com/staticfiles/admin/css/base.css, the url is based off of the folder structure.
Also, it should be noted that in django admin templates, static file paths are said to look into a folder named admin like so: {% static "admin/css/base.css" %} (admin static file paths are hard-coded).
# a line from admin/base.html
<link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% static "admin/css/base.css" %}{% endblock %}">
This means that you cannot change the path after example.com/staticfiles/ for admin static files.
But, can be done by copying the templates directory
Copy templates directory from venv/Lib/site-packages/django/contrib/admin/ to project base folder
Find all the occurrences of {% static "admin/ and replace {% static "admin/ with {% static "manager/ in the templates. Need to be careful not to change any other thing in the template files.
Update TEMPLATES settings > 'DIRS': [os.path.join(BASE_DIR, 'templates')]
Overriding Admin Templates
Another possible way to achieve this could be rewriting the URL to remove or replace admin from the URL. Simply rewriting the URL would result in 404. Furthermore, server configuration for serving the admin static files has to be additionally added.
You're solving the wrong problem. Firewalls have standard rules to get you started, but must be customized to match the environment they're protecting, not the other way around.
Renaming files and routes each time you install or upgrade something is time consuming and error prone. Make exceptions for routes that exist - they are valid routes, so teach the WAF about them.
Just think about it this way: you would never post a question like this:
"I've just bought a firewall. What application framework can I use that can be put behind it, without needing to change the framework?"

Django | Why use {% load static %} and make template compiler work more?

For static resources like images/CSS/Js I can directly use their path
<link rel="stylesheet" href="/static/css/default.min.css">
#in app level templates:
<link rel="stylesheet" href="/static/myapp/css/app.min.css">
why add clutter to the template with:
{% load static %}
<link rel="stylesheet" href="{% static 'css/default.min.css' %}" />
unless you are dynamically adding part of the path or version at the end of url.
I suspect templates with {% load static %} would be less performant(may be ignorable, but still why?)
Please kindly enlighten me, i think there might be a strong reason.
Hard Coding it like that can create a few problems in production.
Instead it's a good idea to create static root in the settings and always use that. Further more if django knows it's a static file, it will not only look in the "hard coded" location but in other possible locations too.
Well, you kinda answered your own question when you said unless you are dynamically adding part of the path, which is exactly what you are doing. And there is a strong reason too.
The 'static' is your STATIC_URL. Forget the static_root, it's a place where you "collectstatic" and then move it to a production location.
I have a Saas django portal deployed somewhere, in production my STATIC_URL (yea 'static' becomes the following:
https://some-cdn-somewhere.com/me-static-assets/static/ I let some performant CDN serve static assets after moving the collected files to it somehow.
For emphasis, I do this for performance and you may decide to use a web server like nginx to serve static assets, they are static afterall and nginx is extremely performant for such. Typically you configure your static url and let nginx serve that one from a folder (STATIC_ROOT) and proxy the other urls to say gunicorn.
Consider the well written django docs for more info https://docs.djangoproject.com/en/3.0/howto/static-files/deployment/

django static files not served to HTML-EMail template

I am running Django on a local Vagrant arch machine on a Win7 host. I set up my environment variables from Django in a .env file. In my app all static files are served correctly and everything works as it should.
Problem: I am not able to serve my static files (images) in my html-email templates. Until now i served them as hardcoded filer URL's and i want to change that.
I am passing BASE_URL BASE_URL=http://127.0.0.1:8001, which is proved working, as context to the template and loading static as usual:
{% load static %}
and calling it in HTML tag:
<img src="{{BASE_URL}}{% static 'img/my_image.png' %}">
In the received email the URL of the image is http://127.0.0.1:8001/static/img/my_image.png which looks right but triggers a 404.
What am i missing??
(Please dont ask me if the image is in the corresponding folder, it is ;)
As already said by #dentemm: Your email service provider try to fetch images from http://127.0.0.1:8001/static/img/my_image.png but he cannot while address of your server is visible only from your local computer. Therefore images are not found. One way to solve this is to render template and take screenshot of template and send that in email body(to see if it renders properly) E.g. here.
Another way is to upload img files to some publicly accessible server.

Beginner: Django dev server external static files

Disclaimer: I am a beginner to Django but have Drupal programming experience.
I have spent some time Googling but can't find the answer to this question: How can I make the Django dev server show images (thumbnails of TIF's in my case) that come from outside the STATIC_ROOT and MEDIA_ROOT of python manage.py runserver 80? For example:
# something.html -- a template file -- WORKS AS EXPECTED BUT SEE NEXT EXAMPLE
<img src="http://www.google.com/someDir/someFile.TIF" height="y" width="x">
# BETTER EXAMPLE -- hdrive COMES FROM USB INSERTED AT RUNTIME
<img src="/hdrive/someFile.TIF" height="y" width="x">
Thanks!
This doesn't make any sense.
Remember that <img src=... is a part of the rendered template that is sent to the client's browser. Why would we want the client to be able to fetch any file in any directory they wanted from the server? (i.e.download $$$)
STATIC_ROOT and MEDIA_ROOT are two designated folders on the server that hold any files we want to be accesible from the outside, i.e. the clients browser.
On the other hand, before or during rendering the template (i.e. before the HTML file is sent from the server to the client) we can open files from outside these two directories using simple python file reading techniques.
For example, we could open an image saved in a directory outside MEDIA_ROOT or STATIC_ROOT, do something to it and copy the result into the MEDIA_ROOT meaning that the client could then read that file at /media/copied_file.png
It seems you are getting confused between the various stages of the request cycle.

Serving static media in django application

I notice that when I reference my java scripts and static image files from my templates, they show up in development, but not from the production server. From development, I access them as such:
<img src="/my_proj/media/css/images/collapsed.png" />
but from production, I have to remove the project directory:
<img src="/media/css/images/collapsed.png" />
I'm assuming I'm doing something wrong with regard to serving static media.
I'm caught between a number of seemingly different options for serving static media in Django. On one hand, it's been recommended that I use django-staticfiles to serve media. On the other I see reference to STATIC_ROOT and STATIC_URL in the documentation (with caveats about use in production).
I have small .png files of "plus" and "minus" symbols for use in some of my jQuery scripts. In addition, the scripts themselves need to be referenced.
1) Am I correctly categorizing scripts and site images as static media?
2) What is the best method to access this media (from production)?
You shouldn't keep the URLs hardcoded that way.
If you're running thedev version of Django, you should check this doc.
If you're not, for simplicity, you can use {{ MEDIA_URL }} and configure that variable in your settings for dev and for production.
<img src="{{ MEDIA_URL }}/media/css..." />
Keep in mind that you'll have to use RequestContext, see more here on docs here and here.
Also, you should server all your static files directly trough a proper webserver. You can configure apache or nginx to do that.
Sigh. There is only one way to serve static media in production, and that is to get the webserver - eg Apache - to do it. Django-staticfiles is for development only, and this is clearly stated throughout the documentation.