Django - absolute path image not showing up - django

I am trying to display an image with the src equal to an absolute path. This is what I did in the template
<img src="/home/userName/Documents/app/userPhotos/1/uploadedPhotos/imageName.png" alt="" />
and it does not show up. I'm positive that it is the correct absolute path. Is there anything I need to do, say in my settings.py file, to be able to use absolute paths? Do I need to
import os
in my template?
Edit:
Just in case it helps, when I run the server and go to the url which calls the template (/displayImages/, this is what it says in my terminal:
[23/Feb/2014 12:07:27] "GET /displayImages/ HTTP/1.1" 200 413
[23/Feb/2014 12:07:27] "GET /home/userName/Documents/app/userPhotos/1/uploadedPhotos/imageName.png HTTP/1.1" 404 2993

As Daniel wrote in his answer, you should not use absolute path for any content on your website. This leads to a security concern and to a not working statement position. When the browser sees /absolute/path/img.png, it searches for this path starting at the root of your website. So, this can become /home/userName/Documents/app/absolute/path/img.png, which doesn't exists.
The right way is:
Read the doc :)
Add (or use) the settings.STATIC_URL defined in settings.py. The default path is the folder static/ in your app folder.
Use {% load staticfiles %} and {{ static "relative/path/file.ext" }} in your template

Why would you use a file path in your template? You should be using a URL, absolute or relative: the address where that image is being served from.

Related

The joined path (relative path) is located outside of the base path component (full path)

I am trying to use thumbnail packages to generate thumbnail images from base images. Originally, I had my source images in my static dir, and as the thumbnail packages want to generate them to my media dir, I thought that was the cause of the SuspiciousFileOperation error I was getting.
No problem, I just copied my images to my media dir, which I thought would solve the issue, but no, the issue remains.
From what I can tell, it seems to be a problem with having a relative path vs a full path?
The full error is:
SuspiciousFileOperation at /toys/
The joined path (/media/images/test.jpg) is located outside of the base path component (/home/username/django/first_webapp/my_site/media)
The path /home/username/django/first_webapp/my_site/media/images/test.jpg is valid and test.jpg is a valid jpg image.
The abridged code I am using in my template, with sorl-thumbnail (although I have also tried with easy_thumbnails) is:
{% for instance in prods %}
<img src=" {% thumbnail instance.image_url 300x300 %} ">
{% endfor %}
instance.image_url, in this case, is set to /media/images/test.jpg
My media directory settings from my settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
I am unsure where to begin to troubleshoot this.
I can't really understand how you think the type of the field is not relevant. Of course it is.
In your case, you have (for some reason) used a TextField to store the path of your image file. TextFields have no special knowledge of media files, and sort-thumbnail just treats the contents as a path component, which it then joins with MEDIA_ROOT. But since your path begins with a leading slash, the result of os.path.join(MEDIA_ROOT, path) is just path; the leading slash means exactly "start from the filesystem root". So the result is a path outside your project, which Django disallows for security reasons.
A quick fix is to remove the leading slash - as well as the duplicate "media" prefix - and just store "images/test.jpg". But the real fix is to use the appropriate field for the content you are storing, and let that field manage it for you.
For anyone who lands here off Google because upgrading their Django and easy-thumbnails caused the same error to start happening, check that your template is referencing your ImageField as {{image_field|thumbnail_url:'default'}}, not {{image_field.url|thumbnail_url:'default'}}.
Apparently it got less forgiving of that mistake.

Is it possible to hardcode CSS link in django?

I have an django project and want to hardcode a link to CSS (I do not want to use STATIC_FILES...etc). The reason is because I want to be able to click index.html and it will work on browser (including getting the css file).
I put both index.html and index.css in the same directory and added this line in index.html:
<link rel="stylesheet" type="text/css" href="./index.css"/>
When I double-click index.html, it imports index.css perfectly.
However, when I load it with the django development server and open via browser, it does not import the index.css.
What should be done so that index.html takes the index.css?
The answer by Christopher Schäpers works nicely, I'd like to extend her answer by showing how you may actually do what she suggests.
Let's say you have
<link rel="stylesheet" type="text/css" href="/index.css"/>
which means the browser is requesting to localhost:8000/index.css, so in your root urls.py file, you add something like this
from django.urls import path
from django.conf import settings
from django.http import HttpResponse
def css_path(request): # This is basically a "view"
path = settings.BASE_DIR / 'index.css' # For earlier Django version: os.path.join(settings.BASE_DIR, 'index.css')
with open(path, 'rb') as f:
content = f.read()
return HttpResponse(content, content_type='text/css')
urlpatterns = [
# ... (your other url patterns)
path('index.css', css_path)
]
NOTE: Remember to set the content_type keyword argument correctly base on what you are serving (Example: application/javascript for .js, image/png for .png, .etc).
That's because the browser uses a directory based approach.
Say your template directory looks like this:
/home/yura/project/templates/
→ index.html
→ index.css
When opening index.html with your browser it plainly looks for index.css in the same directory, thus for /home/yura/project/templates/index.css.
Now when you run the development server it's not directory based anymore. There's the urls.py file that specifies where each path leads to.
You probably have a route / that leads to index.html even though index.html isn't called nothing. You could also add a route /blog/ that may lead to blog_home.html even though the file is called blog_home.html.
Every url that enters django is routed through the urls.py file.
This is one of django's core concepts. URLs should be user-typable and readable without cruft as .php, .html and so on that comes from directory based approaches like PHP or CGI.
Since you haven't defined a route called /index.css thus index.css isn't found.
If the thing you are doing is a one-off your best bet would be to just add a route to /index.css that delivers index.css.
Otherwise there is no way of doing this, since django isn't directory based, as pointed out above.
You might then want to think about why exactly you want to be able to open the raw html file directly in the browser too, since it makes the django templating language entirely useless for you, thus you can't do anything variable, loop and logic related and are stuck with basic html where you, instead of the django-dev server could just as well use a simple http-server instead.

Flask import static resources

The problem: I get a 404 when I access static resources from any route other than '/'.
I have an image called volume.png in my static folder in my Flask application. When I route my main page to '/' using #app.route('/') it finds the image fine, and I can display the image when I hit localhost:5000/static/images/volume.png. But when I use any other link, for example, '/s', it says it can't find the image in s/static/images/volume.png. Even when I create an s directory and copy the static directory to it, I get a 404 when I type localhost:5000/s/static/images/volume.png. I've considered using Flask-Assets, but there doesn't appear to be much documentation or examples. What's a good way to make sure my routes have access to the static resources?
You need to qualify the path to your image in your HTML (or CSS):
<!-- This will break in the way you describe -->
<img src="static/images/volume.png" />
<!-- This will not -->
<img src="/static/images/volume.png" />
<!-- Nor will this (assuming you are using a Jinja template) -->
<img src="{{ url_for('static', filename='images/volume.png') }}" />
The reason for this is because of the way that user-agents are required to resolve relative paths for URIs (see section 5.1 of RFC 3968 for the details).
Using static/images/volume.png results in the following path at /:
scheme://host.name/static/images/volume.png
and the following at /s:
scheme://host.name/s/static/images/volume.png
as you have discovered. By ensuring that you provide an absolute path component (at the very least) for your resources, you ensure that the browser will merge your provided path with only scheme and host.name, rather than with scheme, host.name and path.

Django CSS & Static Media Not Loading

So I've been hitting my head against the wall on this for the last hour and can't seem to figure out why none of the static media (CSS, Images, JS etc) when my template is rendered.
Could someone please help me find out why adjustments I need to make? Below are snippets from Settings.py, Index.html and stylesheet please let me know if more is needed.
My static files are located in the following directory:
/djangoproject/website/static
Settings.py - Located /djangoproject/djangoprojectname/
STATIC_ROOT = os.path.normpath(os.path.join(PROJECT_ROOT,
"/static/"))
STATIC_URL = '../website/static/'
Here's a snippet from my index.html that is supposed to be calling the css style sheet with {{ STATIC_URL }}
Index.html - Location /djangoproject/website/templates/
<link rel="stylesheet" href="{{ STATIC_URL }}css/style.css">
Location of CSS StyleSheet
style.css - Location /djangoproject/website/static/css/
From the Django docs:
If {{ STATIC_URL }} isn't working in your template, you're probably
not using RequestContext when rendering the template.
As a brief refresher, context processors add variables into the
contexts of every template. However, context processors require that
you use RequestContext when rendering templates. This happens
automatically if you're using a generic view, but in views written by
hand you'll need to explicitly use RequestContext To see how that
works, and to read more details, check out Subclassing Context:RequestContext.
It seems to me that you are setting STATIC_URL to a path, when it should be set to, well, a URL. You need to set this to the web address of the folder that contains your css files, for example:
STATIC_URL = 'http://mydomain.com/static_files/'
Try to find your CSS file online by typing the address you expect it to be into your browser. Once you find the CSS file this way, just copy the root URL that got you there.

Django: Error 500 for favicon

On my local server, I'm getting the following error in terminal
[03/Oct/2011 22:49:19] "GET /favicon.ico/ HTTP/1.1" 500 65893
In my site_base.html, I already have the following line:
<link rel="icon" href="{{ STATIC_URL }}images/favicon.ico" />
What's causing this error and how can I make it stop?
The default lookup browsers do is /favicon.ico. However, since you specified the link the browser shouldn't be doing this. There's most likely a bug in the particular browser and version you're using responsible for sending the extra request, but that's beside the point.
You're getting a 500 error because that particular request is making it into the Django URL handling machinery, and whatever view is responding to, is choking on the provided arguments.
Check your urls.py and see which pattern(s) will accept the URL /favicon.ico/. Then, go into the corresponding views and see why it's causing it to choke, or alter the pattern such that it won't catch a URL like this, as it mostly likely shouldn't be in the first place.
This may not be 100% the issue that you're facing, but it's worth mentioning since you're using a custom favicon stored in your static folder.
In Django templating, you can manage your static assets like this:
{% load static %}
<link rel="shortcut icon" href="{% static 'img/favicon.ico' %}">
No need to send a {{ STATIC_URL }} context variable into the template.
In my case, the problem was appearing when I was trying to log in on the admin panel.
My error was:
ValueError: unsupported format character 'C' (0x43) at index 34
Internal Server Error: /favicon.ico
The problem was nested in my urls.py:
Suggestions from other users help me a little but in the end, the documentation was a game changer. Quote:
from django.contrib.staticfiles.storage import staticfiles_storage # for `favicon` -> https://simpleit.rocks/python/django/django-favicon-adding/
from . import views
urlpatterns = [
path('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url('project_foo\logos\media\favicon.ico')))]
I mean line: path('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url('project_foo\logos\media\favicon.ico')))]
As the documentation stated quote: django.contrib.staticfiles collects static files from each of your applications (and any other places you specify) into a single location that can easily be served in production.
In my case, I pointed out a file, not the location. Things were ok on the user page, but throw an error on the admin panel.
The solution in my case is:
`path('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url('project_foo\logos\media')))]`