Миграция данных из ImageField в ImageField с использованием South - PullRequest
4 голосов
/ 06 августа 2011

Я пытаюсь в течение нескольких часов выполнить самую глупую миграцию, используя Юг, но каким-то образом я с треском провалился ... Я пытаюсь перейти на Sorl-Thumbnail.

Вот мойПереходная модель:

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')

И моя прямая миграция такова:

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()

это самая последняя версия этого кода.Все остальные, в основном, не смогли правильно разместить файл изображения в новом каталоге.

Help ...:)

Время идет ....

Хорошо... После нескольких тестов я получил этот код:

 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()

Изображения копируются и сохраняются в новом столбце (new_image), но дело в том, что все файлы сохраняются в корне MEDIA_ROOT,не в нужном подкаталоге ('new_deal_images').Я попробовал это в * строке, но все равно не повезло:

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

Подоконник не работает ...

Пожалуйста, помогите ...:)

Другое время идетby ....

ок ... Я думаю, что с Югом есть серьезная проблема:

Этот код отлично работает в Django Shell, копируя все файлы в нужное место:

 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()

Но этот код в файле миграции не создает дамп всех файлов в корневом каталоге MEDIA_ROOT, не перемещая его в правильный подкаталог:

 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()

Ответы [ 4 ]

4 голосов
/ 30 ноября 2011

Вы можете переопределить метод generate_filename поля в южной части. Например, это скопирует все изображения в поле «изображение» в поле «new_image», просто изменив каталог, в котором они хранятся.

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()
3 голосов
/ 01 ноября 2011

У меня была та же проблема, и я обошел ее, назначив путь вместо файла:

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()
1 голос
/ 08 декабря 2012

Благодаря ответу Майка Фогеля я решаю эту проблему в процессе миграции, которая перемещает изображения из одной модели в другую:

from south.v2 import DataMigration

from .. models import upload_by_conditions
from .. models import RESOURCE_IMAGE


class Migration(DataMigration):

    def forwards(self, orm):
        src = orm['uploader.Queue']
        dst = orm['uploader.Resource']
        for item in src.objects.all():
            obj = dst(
                kind=RESOURCE_IMAGE,
                file_name=item.file_name,
                file_type=item.file_type,
                file_size=item.file_size,
            )
            # here I assign own handler!!!
            obj._meta.get_field('resource').generate_filename = upload_by_conditions
            obj.resource.save(item.file_name, item.image, save=True)
0 голосов
/ 23 февраля 2013

Миграция ImageField из одного хранилища в другое хранилище с югом

Хотя это может и не дать прямого ответа на ваш вопрос, я решил добавить потенциально полезную информацию в тему миграции на django south imageField (Вопрос в настоящее время лучший ресурс в Интернете для).

Одна существенная проблема с обработкой Югом полей изображения при переносе данных заключается в том, что в качестве побочного эффекта его ORM-Freezing, по-видимому, предполагается использование DefaultStorage, поскольку хранилище не зависает.Так что, если у вас есть специальное хранилище для ваших полей, то, вероятно, не будет работать должным образом.Но @cberner дает отличное представление о том, что вы можете сохранять файлы и манипулировать ими напрямую, напрямую используя хранилище, а затем просто указать путь к полю и сохранить его.В ответ на его ответ я предложил следующую миграцию данных, чтобы перенести все существующие образы из одного хранилища (по умолчанию, хранилище файловой системы) в новое хранилище (AWS):

вот миграция из хранилища по умолчаниюв новое хранилище (запускать одновременно с добавлением нового хранилища в определение поля):

def forwards(self, orm):
    new_images_storage = ImagesS3Storage()

    for food in orm.Food.objects.all():
        try:
            new_file = ContentFile(food.image.read())  # south will use the default storage
            new_file_path = new_images_storage.save(food_image_upload_to(food, food.image.name), new_file)
            food.image = new_file_path
            food.save()
        except ValueError:  # food with no image
            continue

(Для справки, вот мое настраиваемое хранилище с корзиной, отличной от корзины AWS по умолчанию, которая уже используетсямое хранилище статических файлов)

class ImagesS3Storage(S3BotoStorage):
  def __init__(self, *args, **kwargs):
    kwargs['bucket'] = getattr(settings, 'FOOD_IMAGES_BUCKET_NAME')
    super(FoodImagesS3Storage, self).__init__(*args, **kwargs) 

Надеюсь, это поможет потерянной душе.

...