Displaying image held in ImageField in a django template - django

I'm trying to display an ImageField image in my django template.
I'm doing it as such:
<img src="{{ pic.content.url }}" />
This, however, shows an image for mysite.com/appname/appname/picturename.ext. (which I'm like 90% sure is wrong; I don't know what's right, though. The images are kept in the larger django-site folder, and I don't know if apache can serve them directly by url)
My site settings.py file has the media directory correct (it uploads using the admin page and all that jazz), but this merely isn't working.
How do I show the image?

I am assuming you have done the required MEDIA settings. Make sure you are passing the RequestContext from your view and try changing your src to
<img src="{{MEDIA_URL}}{{pic.content.url}}" />
Update:
I think you need to change your media settings:
MEDIA_ROOT = '/var/www/mysite/media/' #This needs to point to the media folder
MEDIA_URL = '/media/'

Related

Can't cope with images uploaded by a user during development

Django 1.9.7
Could you help me cope with user uploaded images. I have managed to save images.
But I can't show them. So far this is all about development stage (not production).
The bottommost code sample shows the html when I execute "View page source" in Chrome. This "src="/home/michael/workspace/..." is absolute path. It will work if I create such html and open it in the browser without a webserver.
But whey I run the Django dev server, the image doesn't show.
Could you give me a kick here.
/pharchive/pharchive/settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, '../media/')
MEDIA_URL = os.path.join(BASE_DIR, '../media/')
/pharchive/pharchive/urls.py
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
/pharchive/masterdocument/models.py
class Image(AbstractDocument):
image = models.ImageField(upload_to='images/%Y/%m/%d')
/pharchive/masterdocument/views.py
class ImageDetailView(DetailView):
model = Image
/pharchive/masterdocument/templates/masterdocument/image_detail.html
<html>
<img src="{{ object.image.url }}"/>
</html>
view-source:http://localhost:8000/images/6/
<html>
<img src="/home/michael/workspace/pharchive/media/images/2016/06/29/Screenshot_from_2016-02-23_205205.png"/>
</html>
MEDIA_URL should be the root URL for uploaded media, for example:
MEDIA_URL = '/media/'
You have set it to the path the the folder where uploaded media are copied.
Edit: as requested more information on how that works.
What you are trying to do is store an image file submitted by a user, and then serve it to other users. To store the file, you need to specify a location on the filesystem where to store it, in your case:
/home/michael/workspace/pharchive/media/images/2016/06/29/Screenshot_from_2016-02-23_205205.png
Django builds this path by concatenating these parts:
the MEDIA_ROOT
the ImageField's interpolated upload_to attribute, here 'images/%Y/%m/%d' interpolated to images/2016/06/29
the file name, here Screenshot_from_2016-02-23_205205.png.
Django also stores in the database the path to the file, relative to the MEDIA_ROOT, in your case images/2016/06/29/Screenshot_from_2016-02-23_205205.png
Now, to serve the stored file to your users, it first needs to be accessible through a URL, this URL is built by concatenating the MEDIA_URL setting to the path stored in the database (maybe modified to make it URL compatible), here it gives /media/images/2016/06/29/Screenshot_from_2016-02-23_205205.png.
The last step is to actually serve the file when the previously constructed URL is accessed, typically it will not be done the same way in development and in production.
In development, the Django devserver will be used to serve the file, which is why you add a url pattern when DEBUG is true. That url pattern will map any URL starting with the MEDIA_URL (/media/) to a view that will read the stored file and return its content.
In production you will use a dedicated web server to serve uploaded files, for performance reasons.

Live site not finding image file

I currently have the function of uploading images on my site. All the images are working uploading correctly, but when I try to display them using the image.url attribute in the view, it gives me a 404 not found error.
My believe it might be something with my Apache config or Django settings.py.
In my Apache config under I have:
Alias media/ /var/www/MySite/media/
<Directory /var/www/MySite/media>
Require all granted
</Directory>
In my settings.py:
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media')
MEDIA_URL = 'media/'
In my view I am trying to display the image as follows:
{% for photo in photos %}
<div class="col-md-3 photo-wrapper">
<img src="{{ photo.image.url }}"/>
</div>
{% endfor %}
The image then looks for this url:
http://mysite.co.za/media/profile_photos/photo.png
But it doesn't find the image.
I did check that the image gets uploaded and it does to the correct location.
Also my model for clarification:
image = models.ImageField(upload_to='profile_photos')
Note: This is working fine when I work with the site on my localhost.
Edit:
So while I was trying different fixes I messed up some stuff that caused me to change the Debug in the settings.py to True, then I saw the image was actually being shown. I changed the debug to false again and the image was once again not showing. What would cause dubug to influence this?
The apache alias directive should start with a /
Alias /media/ /var/www/MySite/media/

upload images to template directory

I have a model with this field:
image=models.ImageField(upload_to='company-category')
company-category is a folder in uploads folder,but I want to upload images to template directory .I think this way users that visit my website can't access images and download them.
in settings:
TEMPLATE_DIRS = (
"C:/ghoghnous/HubHub/Theme"
)
how can I do this?
Here I'm giving two solutions. The one you asked and then my suggestion.
Use the following code to set the upload location to your templates folder.
from django.conf import settings
image=models.ImageField(upload_to = settings.TEMPLATE_DIRS[0])
The above code will upload image to your template directory.
My Suggestion:
Upload images to your media folder. Then use the MEDIA_URL to allow users to download them. Use the following code to define them.
settings.py
MEDIA_ROOT = 'C:/ghoghnous/HubHub/media'
MEDIA_URL = 'site_media'
urls.py
from django.conf import settings
urlpatterns += patterns('',
url(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
)
models.py
class SampleModel(models.Model):
image = models.ImageField(upload_to = 'images')
If you use this, the images will be uploaded to the folder C:/ghoghnous/HubHub/media/images/. Then get your required images by using objects.get or objects.filter.
record = SampleModel.objects.get(id = 1)
If I print record.image, the output will be images/filename.jpg.
Pass this to your template. Then you can display the image or give download link as follows:
<a href="{{ record.image.url }}/" >Download</a> #Download link
<img src="{{ record.image.url }}/" /> #To display image
<a href="/site_media/images/file.jpg" >Download</a> #Download static files
I suggest you using the second method, since saving images in templates folder is not adviced.
Template directory is not a preferred place to store media as per Django good practices.
Also, any images that you display on the web page will have a path and can be downloaded. Some people use scripting to stop right clicks and stuff like this but as far as I understand source code always give you image paths.
Oh, I think you'd like to upload the file to a temporary folder and then do something with it. Right?
You need to override method clean_image in forms. Then you can write your own code with any path you want using File storage

Django admin view uploaded photo

I have implemented photo upload in Django but I have a problem to view it Django admin.
models.py
class WorkPlacePhoto(models.Model):
file = models.FileField(storage=FileSystemStorage(location=settings.MEDIA_ROOT), upload_to='uploads')
Photos are saved in PATH_TO_APP/media/uploads/ and I can view them in my app. However, in admin panel, when I clicked on the link which admin app is generated it gives me 404 error as
Request Method: GET
Request URL: http://127.0.0.1/admin/wpphotos/workplacephoto/9/media/uploads/aosa_glb_ho_778_hi.jpg/
u'9/media/uploads/aosa_glb_ho_778_hi.jpg' object is not found
Although the message is clear, I couldn't figure out which url should be written to view the image and of course how admin class should be modified.
I glad to suggest me a way to achieve this. Thanks...
From you description I am guessing your MEDIA_URL isn't set correctly, something which is a bit tricky to do using the Django development web server.
I am guessing that the link's href would probably be media/uploads/aosa_glb_ho_778_hi.jpg where you probably want /media/uploads/aosa_glb_ho_778_hi.jpg so it is relative to http://127.0.0.1/ not to where you happen to be now http://127.0.0.1/admin/wpphotos/workplacephoto/9/.
See the static files documentation for inspiration of how to serve your images with the Django development server.
I have the same issue but I managed to fix it -but it's not a correct method and I'd like to use a better solution if possible.
What I did was, I have apache running on port 80, so I created a symbolic link in the /var/www folder which is pointing to the Images folder in my Django App directory. And the Media URL is basically this:
MEDIA_URL = 'http://127.0.0.1/Images/'
This work fine, but I don't like the solution.
I didn't quite follow the solution explained above. Could someone please explain more?
By now, you probably either solved your problem or quit it altogether, but after all these years people (like me) still have this problem. Here's how I just solved it:
On settings.py, I set not only STATIC_URL (with the name of the static folder) and STATIC_URL (with the path to that folder) but I also set MEDIA_URL and MEDIA_ROOT accordingly, where the uploaded images will be stored at;
On my model class, I have my picture field looking as follow:
picture = models.FileField(upload_to='images/')
It will upload the image to my MEDIA_ROOT folder, appending /images/ to it.
And finally, on my urls.py, my urlpatterns looks like this:
urlpatterns = [
url(r'^admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Notice how I appended the static right after the list.
Django's documentation makes it clear that this strategy is not recommended for production environment and it gives some alternatives you can choose from. For more information: https://docs.djangoproject.com/en/1.10/howto/static-files/#serving-files-uploaded-by-a-user-during-development
You probably have in your settings.py
MEDIA_URL = 'media/'
Being the url relative, you have that behavior in the admin panel. The solution would be to set the url as absolute
MEDIA_URL = '/media/'

Django FileField url not relative

I have something like:
MEDIA_ROOT = '/home/httpd/foo/media/'
MEDIA_URL = 'http://www.example.org/media/'
(...)
file = models.FileField(upload_to='test')
When I create an object with that field in the admin page Django stores in the DB the full file path, like: "/home/httpd/foo/media/test/myfile.pdf". This is contrary to what says in the docs.
All that will be stored in your
database is a path to the file
(relative to MEDIA_ROOT).
When I use the file.url in a template I get something like:
http://www.example.org/home/httpd/foo/media/test/myfile.pdf
instead of what I would like:
http://www.example.org/media/test/myfile.pdf
What am I doing wrong?
I just did a sample FileField in one of my projects and it seemed to work as you are expecting. Here are a couple things to try.
Try making your settings like the following. I know they say it is bad to not end your MEDIA_URL with a / but this is how I do it and I like it better. You just have to remember whenever you use MEDIA_URL in a template to follow it with a slash: href="{{ MEDIA_URL }}/path/to/file"
MEDIA_ROOT = '/home/httpd/foo/media'
MEDIA_URL = '/media'
If that doesn't help anything, create a new simplified model with a FileField nothing customized and see if you are still getting the same problem.