2

Originally my models.py had a field named image using django's models.FileField as seen below:

from django.db import models

class Company(models.Model):
    image = models.ImageField(upload_to='uploads/', null=True, blank=True)

Then I've decided to use django-filer to store the images by adding a new field (new_image) using filer.fields.image.FilerImageField:

from django.db import models
from filer.fields.image import FilerImageField


class Company(models.Model):
    image = models.ImageField(upload_to='uploads/', null=True, blank=True)
    new_image = FilerImageField(null=True, blank=True,
                           related_name="company_image")

Now I'd like to fill the new_image instances with the existing "old" image instances by writing a django migration:

# Generated by Django 3.2.15 on 2023-04-12 

from django.core.files import File
from filer.models import Image
from django.db import migrations


def copy_image_to_filer_image(apps, schema_editor):
    items = apps.get_model('app_name', 'Company')
    for item in items.objects.all():
       if item.image:
          with open(item.image.path, 'rb') as f:
              img_file = File(f, name=item.image.name)
              image = Image.objects.create(original_filename = item.image.name, file=img_file)
              item.new_image = image
              item.save()

class Migration(migraions.Migration):
     dependencies = [
         ('app_name', '0002_auto_foo'),
     ]
     
     operations = [
         migrations.RunPython(copy_image_to_filer_image)
     ]

By applying migrate, we get a ValueError: Cannot assing "<Image: uploads/example.jpg>": Company.new_image must be a "Image" instance.

Marcelo Cordeiro
  • 320
  • 2
  • 12

2 Answers2

0

So doing Image.objects.create() will create an instance of Image and save it to the database, so I think what you need to do here is;

def copy_image_to_filer_image(apps, schema_editor):
    items = apps.get_model('app_name', 'Company')
    for item in items.objects.all():
       if item.image:
          with open(item.image.path, 'rb') as f:
              img_file = File(f, name=item.image.name)
              image = Image(original_filename = item.image.name, file=img_file)
              item.new_image = image
              item.save()
markwalker_
  • 12,078
  • 7
  • 62
  • 99
0

FilerImageField inherits from ForeignKey, so you can assign id of Image directly to foreign key value:

image = Image.objects.create(original_filename = item.image.name, file=img_file)
item.new_image_id = image.pk
item.save()