Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageField is not migrateable with ownwritten migration #4

Open
gregorvolkmann opened this issue Apr 8, 2015 · 3 comments
Open

ImageField is not migrateable with ownwritten migration #4

gregorvolkmann opened this issue Apr 8, 2015 · 3 comments

Comments

@gregorvolkmann
Copy link

Hello @francescortiz,

today I tried to migrate my ImageField (django's ImageField) to a seperate class. Unfortunately, the Iterator iterating the objects start's to bother with your ImageCenterFields, even if I don't touch them for my migration:

00XX_migration.py:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

from image.fields import ImageCenterField

def move_placement_images(apps, schema_editor):
    Placement = apps.get_model("core", "Placement")
    PlacementImage = apps.get_model("core", "PlacementImage")

    for placement in Placement.objects.all(): # ITERATOR THROWS HERE
        PlacementImage(image=placement.image, placement=placement).save()

class Migration(migrations.Migration):

    dependencies = [
        ('core', '0013_auto_20150408_1943'),
    ]

    operations = [
        migrations.RunPython(move_placement_images),
    ]

models.py:

[...]
class Placement(models.Model):
    [...]
    image = models.ImageField( # DJANGO'S IMAGEFIELD
        'Image',
        upload_to='placement/',
        height_field='image_height',
        width_field='image_width',
    )
    image_height = models.PositiveIntegerField(
        'Image Height',
        blank=True,
        null=True
    )
    image_width = models.PositiveIntegerField(
        'Image Width',
        blank=True,
        null=True
    )
    image_center = ImageCenterField(
        image_field = image
    )
[...]

image/fields.py, code in question line 85-97:

def post_init_capture(sender, instance, *args, **kwargs):
    fields = instance.__class__._meta.get_all_field_names()
    for field_name in fields:
        try:
            field = instance.__class__._meta.get_field(field_name)
            if isinstance(field, ImageCenterField):
                image_field = instance.__class__._meta.get_field(field.image_field.name)
                image_instance = instance.__getattribute__(image_field.name)
                image_center_instance = instance.__getattribute__(field.name)
                image_instance.__image_center_instance__ = image_center_instance
                image_center_instance.image_path = unicode(image_instance)
        except FieldDoesNotExist:
            pass

Traceback:

Applying core.0014_auto_20150408_1943...Traceback (most recent call last):
File "./manage.py", line 10, in <module>
  execute_from_command_line(sys.argv)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
  utility.execute()
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
  self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
  self.execute(*args, **options.__dict__)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
  output = self.handle(*args, **options)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 160, in handle
  executor.migrate(targets, plan, fake=options.get("fake", False))
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/db/migrations/executor.py", line 63, in migrate
  self.apply_migration(migration, fake=fake)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/db/migrations/executor.py", line 97, in apply_migration
  migration.apply(project_state, schema_editor)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/db/migrations/migration.py", line 107, in apply
  operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/db/migrations/operations/special.py", line 117, in database_forwards
  self.code(from_state.render(), schema_editor)
File "/Users/USER/Desktop/PROJECT/DJANGO/core/migrations/0014_auto_20150408_1943.py", line 12, in move_placement_images
  for placement in Placement.objects.all():
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/db/models/query.py", line 141, in __iter__
  self._fetch_all()
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/db/models/query.py", line 966, in _fetch_all
  self._result_cache = list(self.iterator())
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/db/models/query.py", line 275, in iterator
  obj = model(*row_data)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/db/models/base.py", line 455, in __init__
  signals.post_init.send(sender=self.__class__, instance=self)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 198, in send
  response = receiver(signal=self, sender=sender, **named)
File "/Users/USER/Desktop/PROJECT/venv/lib/python2.7/site-packages/image/fields.py", line 91, in post_init_capture
  image_field = instance.__class__._meta.get_field(field.image_field.name)
AttributeError: 'NoneType' object has no attribute 'name'

All Placements have images assigned, so none of them are None.

@gregorvolkmann gregorvolkmann changed the title ImageField is not migratable ImageField is not migrateable with ownwritten migration Apr 8, 2015
@francescortiz
Copy link
Owner

This should work.

Placement = apps.get_model("core", "Placement")
Placement._meta.get_field('image_center').image_field = model_class._meta.get_field('image')

I should provide some helper function. Adding it to the TODO

@gregorvolkmann
Copy link
Author

Ran into this problem again today. Thanks for the hint, it works. But I think you have forgotten to replace model_class with Placement. A more general example:

ModelClass = apps.get_model("core", "ModelClass")
ModelClass._meta.get_field('image_center').image_field = ModelClass._meta.get_field('image')

@francescortiz
Copy link
Owner

Thank you for the correction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants