29

私は2つの単純なモデルを持っています:

class UploadImage(models.Model):
   Image = models.ImageField(upload_to="temp/")

class RealImage(models.Model):
   Image = models.ImageField(upload_to="real/")

そして一つの形

class RealImageForm(ModelForm):
    class Meta:
        model = RealImage 

ファイルを UploadImage から RealImage に保存する必要があります。どうすればこれを行うことができますか。以下のコードは機能しません

realform.Image=UploadImage.objects.get(id=image_id).Image 
realform.save()

Tnx が助けてくれました。

4

5 に答える 5

39

Gerard のソリューションに触発されて、次のコードを思いつきました。

from django.core.files.base import ContentFile

#...

class Example(models.Model):
    file = models.FileField()

    def duplicate(self):
        """
        Duplicating this object including copying the file
        """
        new_example = Example()
        new_file = ContentFile(self.file.read())
        new_file.name = self.file.name
        new_example.file = new_file
        new_example.save()

これは実際には、ファイル名に「_1」を追加してファイルの名前を変更するところまで行き、元のファイルとファイルのこの新しいコピーの両方が同時にディスク上に存在できるようにします。

于 2012-06-04T17:51:08.280 に答える
2

フォームを使わずにやってみてください。発生している正確なエラーを知らなくても、フォームの clean() メソッドが upload_to パラメータの不一致のためにエラーを発生させていると推測することしかできません。

これにより、次のポイントに進みます。イメージを「temp/」から「real/」にコピーしようとしている場合は、ファイルを自分で移動するために何らかのファイル処理を行う必要があります (PIL がある場合は簡単です)。

import Image
from django.conf import settings

u = UploadImage.objects.get(id=image_id)
im = Image.open(settings.MEDIA_ROOT + str(u.Image))
newpath = 'real/' + str(u.Image).split('/', 1)[1]
im.save(settings.MEDIA_ROOT + newpath)
r = RealImage.objects.create(Image=newpath)

それが役に立ったことを願っています...

于 2011-07-27T04:44:35.993 に答える
1

私は同じ問題を抱えていて、このように解決しました。

# 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()
于 2012-02-21T22:18:34.470 に答える
-2

Gerard's Solution を更新して、一般的な方法で処理します。

try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

from django.core.files.base import ContentFile

init_str = "src_obj." + src_field_name + ".read()"
file_name_str = "src_obj." + src_field_name + ".name"

try:
    tmp_file = StringIO(eval(str(init_str)))
    tmp_file = ContentFile(tmp_file.getvalue())
    tmp_file.name = os.path.basename(eval(file_name_str))
except AttributeError:
    tmp_file = None

if tmp_file:
    try:
        dest_obj.__dict__[dest_field_name] = tmp_file
        dest_obj.save()
    except KeyError:
        pass

変数の使用:

  1. src_obj = ソース添付オブジェクト。
  2. src_field_name = ソース添付ファイル オブジェクトの FileField 名。
  3. dest_obj = 宛先アタッチメント オブジェクト。
  4. dest_field_name = 宛先添付ファイル オブジェクトの FileField 名。
于 2012-05-10T10:18:31.173 に答える