django images upload dir and template handling - django

I have some model with a FileField() looks like this:
image = models.FileField(upload_to='/Users/john/projects/MyDjangoApp/foobars/images/')
So foobar is some module from MyDjangoApp.
In future there comes another module like barfoos and this will have an own images folder.
What I don't understand is how to handle this in the template.
Now there stand something like:
<td><img src="{{ foobar.image.url }}" height="350" width="350"></td>
So there stand the following:
/Users/john/projects/MyDjangoApp/foobars/images/71RkbKwBxnL._SL1004_.jpg
But it must be, something like:
http://127.0.0.1:8000/foobars/images/71RkbKwBxnL._SL1004_.jpg
All url patterns I find only handle this if the images hosted in /MyDjangoApp/static/images, I wish to handle the files in /MyDjangoApp/foobars/images and later /MyDjangoApp/barfoos/images.
Ho to handle this in Django.
Thanks a lot for your time!

The upload_to argument should be a path relative to your MEDIA_ROOT setting. The url that you'll use to access the file is the same relative path appended to your MEDIA_URL setting.
Also check out the documentation on FileFields and ImageFields and on the MEDIA_ROOT and MEDIA_URL settings

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.

Django: Making alias in urls.py for amazon s3?

I am encountering a problem in setting up the URLs in Django.
To serve my media files I have this Amazon S3 bucket:
https://somebucket.s3.amazonaws.com/
I set the media URL inside settings.py as follows:
MEDIA_URL = https://somebucket.s3.amazonaws.com/media/
Inside the urls.py I set the code as follows:
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_URL}));
My intention is that, when I point an image file from, lets say <img src="/media/image.jpg"/> it will be automatically pointed to http://somebucket.s3.amazonaws.com/media/image.jpg
How can I do that? I have tried many methods but it always returns a 404.
However if i try to access the file directly http://somebucket.s3.amazonaws.com/media/image.jpg it works.
Why would you want to do that? That defeats most of the purpose of having the external storage in the first place. It means that for every media request, it has to go through Django itself, to resolve the URL and generate the redirect to S3, with all the overhead that implies.
Instead, as sneawo suggests in the comments, you should simply set the img src attribute to point to the image via the S3 URL.
turned out that django automatically appends the media_url in front of the imagefield url.
i was under impression that i have to append the media_url, which caused me to look for a simpler solution.
Django Admin only shows relative paths
![django admin shows relative paths][1]
http://i.stack.imgur.com/aZGPy.png
But, tastypie gives me absolute path
http://i.stack.imgur.com/SEdaX.png
so i now don't have to worry about urls anymore...thanks again guys :)

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.

trouble updating media_root in django settings.py

I'm trying to set up a MEDIA_ROOT however when I set this in my settings.py it doesn't seem to be recognized. For example my settings.py looks like:
...
MEDIA_ROOT = '/static/files/'
...
And in a template (to test this change) - I tried:
Media root: {{ MEDIA_ROOT }}
static url: {{STATIC_URL }}
static url displays fine and i can update and change it and those changes are reflected in the test template. However media root is always an empty string. Is there some additional config required to start using MEDIA_ROOT - can someone point me to documentation if so?
There are two context variables which should be available to you by default (as long as you use a RequestContext instance when rendering your template:
MEDIA_URL -- provided by django.core.context_processors.media
STATIC_URL -- provided by django.code.context_processors.static
Both of those context processors are in the default list, as you can see at https://docs.djangoproject.com/en/1.3/ref/settings/#template-context-processors
MEDIA_ROOT is supposed to be a filesystem path, and is used for loading and saving media on disk. There shouldn't be any reason to use it in a template. IF you really need access to it, it is simple enough to write your own context processor to provide it.
The documentation on the media processor, btw, is at https://docs.djangoproject.com/en/1.3/ref/templates/api/#django-core-context-processors-media

Django admin shows full path to uploaded file, and link contains full path. How can I fix this?

I have a model which is defined like this:
class Attachment(models.Model):
file = models.FileField(upload_to=MEDIA_ROOT)
MEDIA_ROOT is defined using it's absolute path, and it's something like d:\django\my_proj\media . In the admin, the link to it appears like this: http://localhost:8000/media/d:/django/my_proj/media/file.txt . How can I fix this?
Use / instead of MEDIA_ROOT. From the docs, upload_to should be:
A local filesystem path that will be
appended to your MEDIA_ROOT setting to
determine the value of the url
attribute.
In other words, the path that you specify in upload_to will be appended to MEDIA_ROOT to form the upload directory, and appended to MEDIA_URL to form the URL to the file.
p.s. it might be worth specifying a subdirectory instead of / just so the uploaded files cannot overwrite your media files. For example, upload_to='uploads/'. To organise you uploads by year/month, you can even do upload_to='uploads/%Y/%m/'. See docs for more details.