Reputation: 7318
I have a model with an image field and I perform all kind of custom logic before image is saved. For example, I resize image and upload it to the server. Then I link it's path to the filename.
So I don't need Django to save the image, which it does overwriting my custom sized image.
What I would like to do, is prevent django imagefield from automatically uploading image to the server. Is it possible to do this ?
Updated with code:
Model:
class Document(models.Model):
myField = models.CharField(max_length=500)
image_main = models.ImageField(blank=True, upload_to=change_filename_to_slug)
image_thumbsize_big = models.ImageField(blank=True)
image_thumbsize_small = models.ImageField(blank=True)
View:
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False) # Creates a modifiable instance
instance.save()
return HttpResponseRedirect('/list/')
else: .....
The function that handles the file upload process. It handles all the process I need, creates file of proper size and put it in directory. Problem is that when the instance is saved by django, it creates the file on it's own, and thus I have 2 files and the wrong one is used. I would only like to short-circuit django and prevent imagefield form creating it's file:
def change_filename_to_slug(instance, filename):
file = instance.image_main
# Variables
save_media_dir = instance.mediaUrl + instance.saveImagepath # Passed by model
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + save_media_dir
im = Image.open(file)
slug = slugify(instance.myField, allow_unicode=True)
finalpath = None
has_iterated = 0
for key, value in sizes.items():
im_reset = im
im_reset = im_reset.resize(value, Image.ANTIALIAS)
save_dir = base_dir + slug + key
field_file_name = save_media_dir
if im.format.lower() == 'png':
# Save in folder : no need to save again
im_reset.save(save_dir + '.png', compress_level=png_compress, format='PNG')
# Save names in fields:
if has_iterated == 0: finalpath = 'dir/' + slug + key + '.png'
if has_iterated == 1: instance.image_thumbsize_big = field_file_name + slug + key + '.png'
if has_iterated == 2: instance.image_thumbsize_small = field_file_name + slug + key + '.png'
has_iterated += 1
return finalpath
The form:
from .models import Document
from django.forms import ModelForm
class DocumentForm(ModelForm):
class Meta:
model = Document
fields = ['myField', 'image_main', 'image_thumbsize_big', 'image_thumbsize_small']
Upvotes: 1
Views: 2085
Reputation: 2539
I would try and overwrite the Form's save
method:
class DocumentForm(ModelForm):
def __init__(self, post_data, files_data):
self.image_main_file = files_data.get('image_main', None)
return super(DocumentForm, self).__init__(post_data, files_data)
def save(self, force_insert=False, force_update=False, commit=True):
instance = super(DocumentForm, self).save(commit=False)
# do your image magic here, e.g.
# instance.image_thumbsize_big = field_file_name + slug + key + '.png'
# you can access your main file with: self.image_main_file
if commit:
instance.save()
return instance
and then in your list-view:
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=True)
return HttpResponseRedirect('/list/')
else: .....
Upvotes: 1