Django admin view uploaded photo - django

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/'

Related

Django - ImageField, upload, store and serve image in development server

I'd like to have an ImageField in the admin form for my model (say, for an individual's profile). And I'd like to display this image in a view later on.
This is the model I have :
class Individual(models.Model):
ind_name = models.CharField(max_length=100)
ind_photo = models.ImageField(default="default.jpg")
def __str__(self):
return self.ind_name
This is what I have in the settings for my website :
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
MEDIA_URL = '/static/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,"static/media")
These are the urls of my app:
urlpatterns = [
url(r'^$', views.index, name="index")
]
I know how to use static files (e.g. CSS, Javascript), and to get them to work in both development and production.
But I have no clue how to get images to work. I've read Managing static files and Deploying static files, but I still don't get it.
With the code above the image gets saved in the proper folder (i.e. /static/media at the level of my site). But I have no clue :
1) how to display it in a template,
2) whether it would be best to keep these images in my app's static folder,
3) and (if 2) whether I would need to run collectstatic every time someone uploads an image in the admin.
Sorry if I'm unclear, but this way more obscure than I thought it would be.
In order for the image to be uploaded and served during development, I had to move the media folder out of the static folder (i.e. create a media folder at the root of my project's folder).
And in my main urls.py, I had to add :
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
as suggested by MicroPyramid.
To display it in a template, for a given Individual "somebody" (from a queryset), I use :
<img src="{{ somebody.ind_photo.url }}">
It is good practice to separate both staticfiles and media files. Yes, you have to do collectstatic all the time when you upload if you store the images in static folder. We can get the image full url from the object like the following.
{{obj.ind_photo.url}}
For more info on files https://docs.djangoproject.com/en/1.10/topics/files/

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.

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 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.

Django - uploaded images can not be retrieved

I am exploring file/images uploads in Django. I have a model with Photo class which has thumb ImageField. I uploaded thumb with admin panel and I made template which just gives <img src='{{photo.thumb.url}}' />. Unfortunately I don't get any images and when I try to get direct link it says "page not found". It seems that django either does not move them to media_url or maybe it has no permission to access it? I wonder what can I do to fix it.
Thanks a lot beforehand.
PS: Running django on dev server with sqlite db.
The development server by default doesn't serve static files (see the documentation). You'll need to add the following code to the bottom of your urls.py to enable static file serving:
from django.conf import settings
if settings.DEBUG:
urlpatterns += patterns('',
(r'%s(?P<path>.*)' % settings.MEDIA_URL[1:], 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
)
That should sort you out.