Копирование файлов с одной модели на другую - PullRequest
3 голосов
/ 31 октября 2011

У меня есть две модели, подобные этой:

class A(models.Model):
    attachment = FileField(upload_to='a')

class B(models.Model):
    attachment = FileField(upload_to='b')

У меня есть экземпляр A модель:

a = A.objects.get(pk=1)

Мне нужно создать экземпляр B модели, с файлом, скопированным из a instance.

Как я могу это сделать?

Я пытался что-то вроде этого, но это не работает:

from django.core.files import File
B.objects.create(attachment=File(open(a.attachment.path, 'rb')))

Ответы [ 3 ]

3 голосов
/ 09 ноября 2011

Это странная вещь. Теперь способ, который я пробовал раньше, работает отлично, без каких-либо ошибок. Может быть, я что-то пропустил в первый раз. Так и работает:

from django.core.files import File
B.objects.create(attachment=File(open(a.attachment.path, 'rb')))
2 голосов
/ 22 февраля 2012

У меня была такая же проблема, и я решил ее следующим образом, надеюсь, она кому-нибудь поможет:

# models.py

class A(models.Model):
    # other fields...
    attachment = FileField(upload_to='a')

class B(models.Model):
    # other fields...
    attachment = FileField(upload_to='b')

# views.py or any file you need the code in

try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO
from django.core.files.base import ContentFile
from main.models import A, B

obj1 = A.objects.get(pk=1)

# You and either copy the file to an existent object
obj2 = B.objects.get(pk=2)

# or create a new instance
obj2 = B(**some_params)

tmp_file = StringIO(obj1.attachment.read())
tmp_file = ContentFile(tmp_file.getvalue())
url = obj1.attachment.url.split('.')
ext = url.pop(-1)
name = url.pop(-1).split('/')[-1]  # I have my files in a remote Storage, you can omit the split if it doesn't help you
tmp_file.name = '.'.join([name, ext])
obj2.attachment = tmp_file

# Remember to save you instance
obj2.save()
0 голосов
/ 31 октября 2011

Ваш код работает, но не создает новый файл.

Для создания нового файла вы должны рассмотреть shutil.copy (): http://docs.python.org/library/shutil.html

Более того, если вы копируете файл, его имя должно отличаться от предыдущего, или вы можете сохранить то же имя, если создаете файл в другом каталоге . Зависит от того, что вы хотите ...

Итак, ваш код становится:

from shutil import copy
B.objects.create(attachment=copy(a.attachment.path, 'my_new_path_or_my_new_filename'))

Также не забудьте .save() ваш новый объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...