Django: Get ImageField url in view - django

I am trying to get ImageField absolute path in Django view so I can open the image, write on it something and then serve it to user.
I have problem getting absolute path for the image which is saved in media folder.
item = get_object_or_404(Item, pk=pk)
absolute_url = settings.MEDIA_ROOT + str(item.image.path)
I get error, that item.image does not have path (The 'banner' attribute has no file associated with it.). item.image is ImageField and I'd like to know how to get absolute path of the image saved in image field (within Django view).

When configured correctly, use .url: item.image.url. Check the docs here.

Maybe this way?
#property
def get_absolute_image_url(self):
return "{0}{1}".format(settings.MEDIA_URL, self.image.url)
see How can I get a list of absolute image URLs from a Django QuerySet?

I just figured out what was the problem... absolute image path is saved in file variable.
Example (in view):
item = Item.objects.get(pk=1)
print item.file # prints out full path of image (saved in media folder)

Related

DRF serializer remove imagefield absolute url

In DRF, now if i save the image the serializer is giving me the image with absolute path. But in my scenario, i don't want absolute path. I just need a image path which is there in DB. In my scenario, i'm hard-coding the image path in json. So i can't use the absolute path. Can anyone suggest some ideas to implement it.
You can use SerializerMethodField. You can return the value as it is stored in the database by doing the following:
class YourSerializer(serializers.ModelSerializer):
image = serializers.SerializerMethodField()
def get_image(self, obj):
return obj.image.file.name
docs: https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
Create custom FileField will solve the issue
class CustomFileField(serializers.FileField):
def to_representation(self, value):
if not value:
return None
if not getattr(value, 'path', None):
# If the file has not been saved it may not have a path.
return None
return value.path
class MyFooSerializer(serializers.ModelSerializer):
my_file_field = CustomFileField()
...
# other code
Above answers are working for list and retrieve method, but i need to add for post and retrieve instead of querying and serializing it again. Below method will work.
Normally for ImageField and FileField will return name but in DRF it's been converted to url for usefulness. So u just need to change there that's it.
In your serailizer, just specify below like that:
Field_name = serializers.ImageField(use_url=False)
So this line will convert absolute url to name as response after Save and Update.
For further reference refer this link

Django: URLField for image: URL from remote or local static file

I have the following field in my Article model:
picture_url = models.URLField(null=True)
article_as_dict is a dictionary obtained from an external source. If it contains an image URL, I want to save that as my URL. However, If there is no URL from external path, I want to reference a local .jpg as a URL (so I can save it to the field). How can this be achieved?
from django.templatetags.static import static
if article_as_dict['picture_url']:
url = article_as_dict['picture_url']
else:
url = static('path/to/local/static_file.jpg')
If i understood correct, it works, try it

How to check that an uploaded file is a valid Image in Django

I have an ImageField in one of my models so that users can upload an image. When a user submits an upload form, I want to verify that the file in question is a fully valid and displayable image.
I tried using PIL to verify that the image was in fact authentic, but using
from PIL import Image
Image.open(model.file)
Image.verify()
No matter what file I give it though, it always throws an exception.
Anyone know of an easy way to verify the file?
Good news, you don't need to do this:
class ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)
Inherits all attributes and methods from FileField, but also validates that the uploaded object is a valid image.
https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ImageField
Also, you should use verify() as follows:
from PIL import Image
im = Image.open(model.file)
im.verify()
you can use a 'Pillow' with 'try,except 'block, before insert image/data to a database or use it where you want,
like my following example for submit ticket support form , 'view.py' file :
from PIL import Image
if request.method=='POST':
# check if attachment file is not empty inside try/except to pass django error.
try:
ticket_attachmet_image = request.FILES["q_attachment_image"]
except:
ticket_attachmet_image = None
# check if uploaded image is valid (for example not video file ) .
if not ticket_attachmet_image == None:
try:
Image.open(ticket_attachmet_image)
except:
messages.warning(request, 'sorry, your image is invalid')
return redirect('your_url_name')
#done.
if 'image' in request.FILES['image'].content_type:
# Some code
else:
# the file is not image
The ImageField doesn't work when the form is not created by the form.py
In fact, if we upload a file, that is not an image, and save it in the image field, it wouldn't raise any error so, the content_type of the file must be checked before saving.

how to download a filefield file in django view

I have filefield in my django model:
file=models.FileField(verbose_name=u'附件',upload_to='attachment/%Y/%m/%d',max_length=480)
This file will display in the web page with link "http://test.com.cn/home/projects/89/attachment/2012/02/24/sscsx.txt"
What I want to do is when user click the file link, it will download the file automatically;
Can anyone tell me how to do this in the view?
Thanks in advance!
You can try the following code, assuming that object_name is an object of that model:
filename = object_name.file.name.split('/')[-1]
response = HttpResponse(object_name.file, content_type='text/plain')
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
See the following part of the Django documentation on sending files directly: https://docs.djangoproject.com/en/dev/ref/request-response/#telling-the-browser-to-treat-the-response-as-a-file-attachment
https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.FileField.storage
All that will be stored in your database is a path to the file (relative to MEDIA_ROOT). You'll most likely want to use the convenience url function provided by Django. For example, if your ImageField is called mug_shot, you can get the absolute path to your image in a template with {{ object.mug_shot.url }}.

Django admin proper urls inside listview

My current target is to give users the chance to download CSV files from the admin site of my application.
I successfully managed to create an additional column in the model's list view this way:
def doc_link(self):
return '%s' % (self.output, self.output)
doc_link.allow_tags = True
This shows the file name and creates the link, but sadly - because it's inside my 'searches' view - it has an URL:
my_site/my_app/searches/files/13.csv.
This is my problem, I would like to have my files stored in the admin media directory, like this:
http://my_site/media/files/13.csv
Does somebody know how to give url which points "outer" from the model's directory?
Maybe somehow tell Django to use the ADMIN_MEDIA_PREFIX in the link?
I'd really appreciate any help, thanks!
I feel like you answered your own question : )
What's stopping you from using ADMIN_MEDIA_PREFIX if you want to?
I think it's strange you would use ADMIN_MEDIA_PREFIX since that's where your admin media lives -- you shouldn't be saving anything there, so maybe more like your MEDIA_URL.
from django.conf import settings
def doc_link(self):
return '%s' % (settings.MEDIA_URL, self.output, self.output)
doc_link.allow_tags = True