Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data Migration from ImageField to ImageField using South

I'm trying for several hours now to do the silliest migration using South, but somehow, I've been failing miserably.. I'm trying to migrate to Sorl-Thumbnail.

Here is my transitional model:

class Deal(models.Model):
  image = ImageWithThumbsField(upload_to='deal_images',null=True,blank=True,sizes=(200,150),))
  new_image = ImageField(upload_to='new_deal_images',default='deal_images/thumb_deal_noimg.gif')

And my foward migration it's this so far:

def forwards(self, orm):
  for deal in orm.Deal.objects.all():
    try:
      image_name = deal.image.name.split('/')[1]
      file_ = File(deal.image.open()) # I've also tried the method read()
      deal.new_image.save('new_deal_images/'+image_name,file_,save=False)
    except:
      deal.new_image = None  # For the default image kick in
    deal.save()

this is the most recent version of this code. All the others, mostly failed to put the image file in the new directory properly.

Help... :)

Time goes by....

Alright... After several tests i got this code:

 def forwards(self, orm):
     for deal in orm.Deal.objects.all():
        file_content = ContentFile(deal.image.read())
        deal.new_image.save(deal.image.name,file_content) *
        deal.save()

The images are being copied and saved in the new column (new_image), but the thing is that all the files are being saved in the MEDIA_ROOT root, not in the desired sub-directory ('new_deal_images'). I tried this in the * line, but still no luck:

deal.new_image.save('new_ideal_images/'+deal.image.name,file_content)

Sill not working...

Please help... :)

Anothe time goes by....

ok... I think that there is some serious problem with South:

This code works perfectly in the Django Shell, copying all the files to the correct place :

 15         for deal in Deal.objects.all():
 16             image_path = deal.image.path·
 17             file_ = File(open(image_path,'rb'))
 18             deal.new_image.save(deal.image.name,file_)
 19             deal.save()

But this code in the Migration file, does not, dumping all files in the MEDIA_ROOT root directory, without moving it to the correct subdirectory:

 15         for deal in orm.Deal.objects.all():
 16             image_path = deal.image.path·
 17             file_ = File(open(image_path,'rb'))
 18             deal.new_image.save(deal.image.name,file_)
 19             deal.save()
like image 215
rrb_bbr Avatar asked Feb 23 '23 08:02

rrb_bbr


2 Answers

You can override the field's generate_filename method in the South orm. For example, this would copy all the images in the 'image' field over to the 'new_image' field, just changing the directory they're stored in.

for deal in orm.Deal.objects.all():
    deal._meta.get_field('new_image').generate_filename = \
        lambda inst, fn: os.path.join('new_deal_images', fn)
    img_data = SimpleUploadedfile(deal.image.name, deal.image.read())
    deal.image.close()
    setattr(deal, 'new_image', img_data)
    deal.save()
like image 183
Mike Fogel Avatar answered Feb 26 '23 21:02

Mike Fogel


I had the same problem, and worked around it by assigning a path directly, instead of a file:

for tagged in orm.ImageTag.objects.all():
   with tagged.image.content:
     filename = tagged.image.content.name.split('/')[1]
     path = default_storage.save('taggedImages/' + filename, tagged.image.content)
     tagged.imageFile = path
     tagged.save()
like image 20
cberner Avatar answered Feb 26 '23 21:02

cberner