Changing name of image uploaded - django

I'm a noob django developer, I can upload images but name of the images have to be changed to image ID or whatever I want.
In addition to this, when I delete entries, images are still resting in the media file but I don't want this.
What I have to add ?
Here is my models.py
from django.db import models
class Flower(models.Model):
name = models.CharField(max_length = 30)
price = models.IntegerField()
image = models.ImageField(upload_to = 'static/media')
def __unicode__(self):
return self.name

To customize the path and filename of where the files are stored, you'll need to define a method for upload_to. Here's an example:
def my_upload_to(instance, filename):
# "instance" is an instance of Flower
# return a path here
return 'my/path/to/storage/' + filename
class Flower(models.Model):
image = models.ImageField(upload_to=my_upload_to)
See https://docs.djangoproject.com/en/dev/ref/models/fields/#filefield
To delete the underlying file, you'll need to make a call manually:
flower = Flower.objects.get(id=1)
flower.image.delete()
You can choose to override your model's delete() method, or use signals pre_delete or post_delete to delete the associated files automatically.
See https://docs.djangoproject.com/en/dev/ref/models/fields/#filefield-and-fieldfile

Related

Dynamically naming an image file with another field name in Django2

I am trying to save an image file with the name changed to that of another field in the same form.
After some experimentation, it works well by using a handler function in the model, just when the object has been returned to the model for saving. I deconstruct the file object and can assign it a name that I want, However, I am not able to deconstruct the Charfield object and dynamically pass the first field name to the image file.
from django.db import models
import os
#handler function to customise file name.
def photo_path(instance, filename):
basefilename, file_extension= os.path.splitext(filename)
return '{add}/{room}/{basename}{ext}'.format
(add='my_Add', room="should_Be_room_type", basename= basefilename, ext= file_extension)
And the model is:
class Room(models.Model):
room_type = models.CharField( max_length=50) # i.e bedroom /living room etc
room_size = models.CharField( max_length=50)
img = models.ImageField( upload_to=photo_path, null=True, blank=True)
def __str__(self):
return self.room_type
in your case, the argument instance would be your Room instance, and you can use it to recover room_type and room_size. As the instance won't be created until after the image uploads, the only thing that won't be available on photo_path will be instance.id, but you don't need it.
Your function then, can be written as:
def photo_path(instance, filename):
basefilename, file_extension = os.path.splitext(filename)
return '{add}/{room}/{basename}{ext}'.format
(add='my_Add', room=instance.room_type, basename=basefilename, ext=file_extension)
Thanks, I ended up solving it in the view.py by using
my_room_type = request.POST['room_type']
initial_obj = form.save(commit=False)
initial_obj.save()
The idea was to get the value entered for the 'room_type' and print it on the image. It now works thanks.

Changing file name on upload using id in Django ImageField

In this model, I want to change the name of the file uploaded in ImageField
class Product(models.Model):
image = models.ImageField(upload_to=content_file_name)
name = models.CharField(max_length=100)
amount = models.PositiveIntegerField()
class Meta:
ordering = ('name',)
def __str__(self):
return self.name
To change the name of image I'm using this function
def content_file_name(instance, filename):
ext = filename.split('.')[-1]
filename = '%s.%s' % (instance.id, ext)
return os.path.join('products', filename)
but the name of my image is None, if I use other fields like 'name', it works. What should I do to change the name with id? Thanks!
The instance's id is not yet created, because the upload_to function is called before the new object is first written to the database.
In most cases, this object will not have been saved to the database yet, so if it uses the default AutoField, it might not yet have a value for its primary key field.
Emphasis from the Django docs
Two alternatives:
Use a uuid.uuid4() value, its easy to create and as unique as the pk.
Another suggestion, if you care about search engines and SEO, use a slugify(instance.name) so that your images can be easier found in the image search of search engines.

How and where do I handle file uploads from django admin?

So ive read over the docs and I have come out a little confused. I have a model as such
class Image(models.Model):
name = models.CharField(max_length=80)
file = models.ImageField(upload_to = 'project_images')
description = models.CharField(max_length=30)
def __unicode__(self):
return self.name
The handling of the file uploads are done through the admin interface, which works but I need to do a few more things to the data based on other fields present when the upload is committed.
Basically the current directory is project_images what i want to do is when saved the images must be placed in ---> project_images/<year>/<month>. The file path saved must reflect this when saved in the database and the filename must also be saved in the name field.
I understand the logic behind doing this;
Check post
Check valid (the ImageField takes care of this already i assume)
Get filename
Get year and month (numbers)
Check if directories exist
If directories dont exist create it, if they do use them
Set the name to the filename
upload and save all
Where am i supposed to specify this? In the model under a save method?
Sorry if this is specified in the docs but this is one area of the docs which just confused me.
Thanks
from django.db import models
import datetime
import os
import uuid
# Create your models here.
def get_file_path(instance,filename):
ext=filename.split('.')[-1]
filename="%s.%s" % (uuid.uuid4(),ext)
return os.path.join(instance.directory_string_var,filename)
class Image(models.Model):
file=models.ImageField(upload_to=get_file_path)
now=datetime.datetime.now()
directory_string_var = 'image/%s/%s/%s/'%(now.year,now.month,now.day)
change your model to above one.
this saves your file with a random name in the folder media/year/month/day.
if you don't want filename to be random just comment out
ext = filename.split('.')[-1] #and
filename="%s.%s" % (uuid.uuid4(),ext)
check this:
how to create year/month/day structure when uploading files with django
So in your model, you can just do:
class Image(models.Model):
name = models.CharField(max_length=80)
file = models.ImageField(upload_to = 'project_images/%Y/%m')
description = models.CharField(max_length=30)
def __unicode__(self):
return self.name
The '%Y/%m' part of upload_to is strftime formatting; '%Y' is the four-digit year and '%m' is the two-digit month
You must check this to:
http://scottbarnham.com/blog/2007/07/31/uploading-images-to-a-dynamic-path-with-django/
I Hope this helped

saving an image as [self.id].jpg on DJANGO admin

I need an admin on django to be able to upload an image that should be saved as /path/{self.id}.jpg
So far I have a database with id,status,title fields and a model with id,status,title,THUMB fields:
class MEL(models.Model):
id = models.AutoField(primary_key=True, editable=False)
status = models.IntegerField(choices=( (0, 'inactive'), (1, 'active') ), default=1)
title = models.TextField(verbose_name='Título')
thumb = models.ImageField(upload_to=upload_path)
class Meta:
db_table = u'MEL'
The problem is that the image is uploaded previously to the model being saved, so I can't save it to "self.id" at this moment.
I think I could save it to /tmp/{uuid} and then renaming it post-save, probably something like:
def upload_path(self, filename):
self.file_uuid = uuid.uuid4()
return '/tmp/' + self.file_uuid
and then a post-save that renames it and delete it from /tmp/
Or I could try overriding this model's save() method to first call super().save(), then process the image upload (which is in a ImageFieldFile object) and rename it to self.id
suggestions?
thanks
You should be able to change the filename using upload_to. I say this because I have done it in projects and the django documentation says so:
https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.FileField.upload_to
The third paragraph down of that link says this: "This may also be a callable, such as a function, which will be called to obtain the upload path, including the filename." [emphasis added]. I'm not trying to be sarcastic I'm just showing that this is and should be possible so something else must be going on.
try something like this. The problem could be that you were leaving off the extension:
def upload_path(self, filename):
basename, extension = os.path.splitext(filename)
return '/'.join(["path",("%s%s" % (self.id, extension))])

Pathname to the image field in Django

I have this model which has Image field to be uploaded. It has a foreign key reference to another class.
from django.template.defaultfilters import slugify
def upload_to(path, attribute):
def upload_callback(instance, filename):
return '%s%s/%s' % (path, unicode(slugify(getattr(instance, attribute))), filename)
return upload_callback
class Data(models.Model):
place = models.CharField(max_length=40)
typeOfProperty = models.CharField(max_length=30)
typeOfPlace = models.CharField(max_length=20)
price = models.IntegerField()
ownerName = models.CharField(max_length=80)
class ImageData(models.Model):
property = models.ForeignKey(Data, related_name='images')
image = models.ImageField(upload_to = upload_to('image/', 'ownerName'),blank=True,null=True)
def __unicode__(self):
return self.property.ownerName
I have refered this This Web Page to create a dynamic field for images to be stored.
My doubt is can I use the onerName as the attribute in (as the ownerName is in the super class) :
image = models.ImageField(upload_to = upload_to('image/', 'ownerName'),blank=True,null=True)
How does Django consider this request that is need to be served?
Please can anyone explain me this?
'ownerName' is not going to work. It's quite complicated to do the definition of what you want to save in the ImageField directly. Maybe you should do something like this:
def upload_to(path):
def upload_callback(instance, filename):
return '%s%s/%s' % (path, unicode(slugify(instance.property.ownerName), filename)
return upload_callback
If you really want to make it as dynamic as possible you have to pass something like 'property.ownerName' to the function, split the string, retrieve attrtibute property from ImageData instance and then attribute ownerName from its foreign key instance.
Though I think this makes things way to complicated and you better define extra functions for different use cases.