'Want to upload an image using a custom upload image function python djano
This is my custom image upload function
def upload_image(file, dir_name, filename):
try:
target_path = '/static/images/' + dir_name + '/' + filename
path = storage.save(target_path, file)
return storage.url(path)
except Exception as e:
print(e)
and this is my model
class MenuOptions(models.Model):
name = models.CharField(max_length=500, null=False)
description = models.CharField(max_length=500, null=True)
image_url = models.ImageField(upload_to=upload_image())
def __str__(self):
return f'{self.name}'
I want to upload the image using my upload_image function, and as you can see it is taking 3 parameters file,dir_name, and the file_name. how can I pass these parameters in my model.ImageField() Also, I want to store the image_url to my database as returned by the upload_image function will it store the file in DB or the URL?
Solution 1:[1]
First of all, you should pass upload_image, not a call to upload_image():
image_url = models.ImageField(upload_to=upload_image)
Second thing, upload_to automatically calls Storage.save() with the passed value. Therefore call inside upload_image() is not needed. upload_image should only return path, where file is supposed to be saved.
function upload_to should take 2 parameters, instance and filename.
Solution 2:[2]
This is my solution for storing files.
You just implement the below function and use it in the model.
import os
import uuid
from django.utils.deconstruct import deconstructible
@deconstructible
class MediaFileNameHash(object):
def __init__(self, base_dir, path):
self.address = base_dir + "/" + path
self.path = path
if not os.path.exists(self.address):
os.makedirs(self.address, exist_ok=True)
def __call__(self, _, filename):
# @note It's up to the validators to check if it's the correct file type in name or if one even exist.
filename = os.path.splitext(filename)
return self.path + '/' + filename[0] + "@" + str(uuid.uuid4()) + filename[1]
for example:
class MenuOptions(models.Model):
name = models.CharField(max_length=500, null=False)
description = models.CharField(max_length=500, null=True)
image_url = models.ImageField(
upload_to=MediaFileNameHash("/media/", "files"),
verbose_name=_("Address")
)
Solution 3:[3]
In other to pass the function name you first of all need to write a function in the model that handles the path like this !
# In you models.py
# will automatically save your image to your custom view
def get_upload_image_filepath(self, filename):
return 'Images/' + str(self.pk) + '/default.png'
class MenuOptions(models.Model):
name = models.CharField(max_length=500, null=False)
description = models.CharField(max_length=500, null=True)
image_url = models.ImageField(upload_to=get_upload_image_filepath)
def __str__(self):
return f'{self.name}'
Well am just going to guide you toward how you can go about this situation , you could refactor your code as it would work in the same sense. this is my solution on how to write your custom view:
# this would be at the top of your view
import base64
import os
TEMP_UPLOAD_IMAGE_NAME = "default.png"
def save_temp_upload_image_from_base64String(imageString, user):
INCORRECT_PADDING_EXCEPTION = "Incorrect padding"
try:
if not os.path.exists(settings.TEMP):
os.mkdir(settings.TEMP)
if not os.path.exists(settings.TEMP + "/" + str(user.pk)):
os.mkdir(settings.TEMP + "/" + str(user.pk))
url = os.path.join(settings.TEMP + "/" + str(user.pk),TEMP_UPLOAD_IMAGE_NAME)
storage = FileSystemStorage(location=url)
image = base64.b64decode(imageString)
with storage.open('', 'wb+') as destination:
destination.write(image)
destination.close()
return url
except Exception as e:
print("exception: " + str(e))
# workaround for an issue I found
if str(e) == INCORRECT_PADDING_EXCEPTION:
imageString += "=" * ((4 - len(imageString) % 4) % 4)
return save_temp_upload_image_from_base64String(imageString, user)
return None
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Blomex |
| Solution 2 | rmaleki |
| Solution 3 |
