Retrieve image with Django Rest - django

I'm a newbie in Django, and I want to ask how to fetch images with Rest Api for Django.
Currently I have a model with an ImageField and I have no trouble uploading images, or fetching the json for my item but when it comes to fetching it I don't have any clue how. I save the images in src\image\ inside the django app root folder.
How do i fetch the image with an url like: localhost:8080/src/image/image1.jpg?

Please, include your urls.py.
Do you have MEDIA_ROOT correctly configured? This is the location where your files are stored/uploaded.
But I assume you'd need to specify endpoint for your media files.
something like this :
from django.views.static import serve
urlpattenrs = [
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
After that, path is the location of your file which you used to store it ( relative to MEDIA_ROOT) .
You can now fetch your files using media endpoint + location of your file in MEDIA_ROOT directory ( you can call the endpoint like you want, i like media )

Related

Django Displaying images uploaded by ImageField properly

I'm building my own porfolio using Django, and I just had a question regarding uploading images using the ImageField.
I uploaded an image through the admin page using ImageField, and after a long search session, finally got my page to display the image successfully.
urls.py
from django.contrib import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('',include('pages.urls')), # main landing page
path('admin/', admin.site.urls),
path('project/',include("projects.urls"))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
projects.html
<img src="{{project.image.url}}">
However, the official django docs say that this is not a good way to deploy a django site. Why is that, and what is the best/proper way to display images?
The reason is also given in documentation:
This method is grossly inefficient and probably insecure, so it is unsuitable for production.
Proper way of deploying media files in production is to use a reverse proxy server like NGINX or Apache, or you can use a S3 compatible storage(like Amazon S3) to serve those media files as well. I can give you an example configuration in NGINX for serving media files:
location /media {
alias /path/to/media/direcoty; # Change to your own media directory here.
access_log off;
}

DRF: Uploading images in Django

I have a profile database for users in which I save their profile image.
I am using DRF to create API's for this.
Now when I save the profile data, it return JSON as:
{
"branch": "CSE",
"year": 2014,
"image": "static/profile_images/abhishek.jpg"
}
this data gets saved in database and even the image get uploaded to the desired folder. Now I want to access this image in the frontend(I am creating an android app in Ionic), so that the profile pic is viewed in the app's dashboard. How do I do it?
At present simply going to the saved path is not working.
I found the answer what I was looking. Actually in Django files can be partitioned into two:
Static files: those files used in the development, creation and rendering of the website or app. Things like
stylesheets, scripts, fonts etc.
Media files: those files that are uploaded during the normal usage of the website or application such as images, pdfs,
videos etc.
So to have upload functionality one needs to add the following in the settings.py
ENV_PATH = os.path.abspath(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(ENV_PATH, '<folder-name>')
MEDIA_URL = '/media/'
and in urls.py add:
urlpatterns = [
.......
your urls
.......
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

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/

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