わかりました、ほぼすべてのことを試してみましたが、これを機能させることはできません。
このコードは、6つの異なる方法で作成しました。
私が実行している問題は、私が書いているすべてのコードが次の動作をもたらすことです:(1)Djangoは2番目のファイルを作成し、(2)新しいファイルの名前を変更して、_ファイル名の最後まで、(3)データを転送せず、基本的に空の名前変更されたファイルのままにします。 'upload_to'パスに残っているのは、2つのファイルです。1つは実際の画像で、もう1つは画像の名前ですが、空です。もちろん、ImageFieldパスはDjango作成を試みます。
それが不明確だった場合、私は説明しようとします:
## Image generation code runs....
/Upload
generated_image.jpg 4kb
## Attempt to set the ImageField path...
/Upload
generated_image.jpg 4kb
generated_image_.jpg 0kb
ImageField.Path = /Upload/generated_image_.jpg
Djangoにファイルの再保存を試行させずにこれを行うにはどうすればよいですか?私が本当に欲しいのは、この効果に対する何かです...
model.ImageField.path = generated_image_path
...しかし、それはもちろん機能しません。
そして、そうです this one や File のDjango docのような他の質問もここで行いました。
UPDATEさらにテストした後、Windows Server上のApacheで実行する場合にのみこの動作を行います。 XPの「runserver」の下で実行している間、この動作は実行されません。
私は困惑しています。
XPで正常に実行されるコードは次のとおりです...
f = open(thumb_path, 'r')
model.thumbnail = File(f)
model.save()
Webから画像を取得してモデルに保存するコードがいくつかあります。重要なビットは次のとおりです。
from Django.core.files import File # you need this somewhere
import urllib
# The following actually resides in a method of my model
result = urllib.urlretrieve(image_url) # image_url is a URL to an image
# self.photo is the ImageField
self.photo.save(
os.path.basename(self.url),
File(open(result[0], 'rb'))
)
self.save()
それは私のモデルから引き出され、コンテキストから少し外れているため、少し混乱していますが、重要な部分は次のとおりです:
質問がある場合や説明が必要な場合はお知らせください。
編集:明確にするために、ここにモデルがあります(必要なimportステートメントを除く):
class CachedImage(models.Model):
url = models.CharField(max_length=255, unique=True)
photo = models.ImageField(upload_to=photo_path, blank=True)
def cache(self):
"""Store image locally if we have a URL"""
if self.url and not self.photo:
result = urllib.urlretrieve(self.url)
self.photo.save(
os.path.basename(self.url),
File(open(result[0], 'rb'))
)
self.save()
モデルがまだ作成されていない場合は、非常に簡単です。
最初、画像ファイルをアップロードパスにコピーします(以下のスニペットでは= 'path /'と仮定)。
秒、次のようなものを使用します。
class Layout(models.Model):
image = models.ImageField('img', upload_to='path/')
layout = Layout()
layout.image = "path/image.png"
layout.save()
Django 1.4でテストおよび動作している場合、既存のモデルでも動作する可能性があります。
ほんの少しの発言。 tvon answerは機能しますが、Windowsで作業している場合は、'rb'
でファイルをopen()
したいでしょう。このような:
class CachedImage(models.Model):
url = models.CharField(max_length=255, unique=True)
photo = models.ImageField(upload_to=photo_path, blank=True)
def cache(self):
"""Store image locally if we have a URL"""
if self.url and not self.photo:
result = urllib.urlretrieve(self.url)
self.photo.save(
os.path.basename(self.url),
File(open(result[0], 'rb'))
)
self.save()
または、最初の0x1A
バイトでファイルが切り捨てられます。
うまく機能し、ファイルを特定の形式に変換できる方法を次に示します(「モードPをJPEGとして書き込めない」エラーを回避するため)。
import urllib2
from Django.core.files.base import ContentFile
from PIL import Image
from StringIO import StringIO
def download_image(name, image, url):
input_file = StringIO(urllib2.urlopen(url).read())
output_file = StringIO()
img = Image.open(input_file)
if img.mode != "RGB":
img = img.convert("RGB")
img.save(output_file, "JPEG")
image.save(name+".jpg", ContentFile(output_file.getvalue()), save=False)
imageはDjango ImageFieldまたはyour_model_instance.imageです。使用例は次のとおりです。
p = ProfilePhoto(user=user)
download_image(str(user.id), p.image, image_url)
p.save()
お役に立てれば
私がやったことは、ファイルをディスクに保存しない独自のストレージを作成することでした:
from Django.core.files.storage import FileSystemStorage
class CustomStorage(FileSystemStorage):
def _open(self, name, mode='rb'):
return File(open(self.path(name), mode))
def _save(self, name, content):
# here, you should implement how the file is to be saved
# like on other machines or something, and return the name of the file.
# In our case, we just return the name, and disable any kind of save
return name
def get_available_name(self, name):
return name
次に、私のモデルでは、ImageFieldに新しいカスタムストレージを使用しました。
from custom_storage import CustomStorage
custom_store = CustomStorage()
class Image(models.Model):
thumb = models.ImageField(storage=custom_store, upload_to='/some/path')
わかりました。既存の画像ファイルパスをImageFieldに関連付けるだけでよい場合は、この解決策が役立ちます。
from Django.core.files.base import ContentFile
with open('/path/to/already/existing/file') as f:
data = f.read()
# obj.image is the ImageField
obj.image.save('imgfilename.jpg', ContentFile(data))
真剣に考えれば、既存の画像ファイルはImageFieldに関連付けられませんが、このファイルのコピーはupload_to dirに「imgfilename.jpg」として作成され、ImageFieldに関連付けられます。
私の意見では最も簡単なソリューション:
from Django.core.files import File
with open('path_to_file', 'r') as f: # use 'rb' mode for python3
data = File(f)
model.image.save('filename', data, True)
ファイルのロードと再保存のオーバーヘッドを発生させずに(!!)、またはcharfieldを使用する(!!!)ことなく、実際のファイル名を「設定」したい場合は、次のようなことを試してください。 -
model_instance.myfile = model_instance.myfile.field.attr_class(model_instance, model_instance.myfile.field, 'my-filename.jpg')
これにより、実際にファイルをアップロードしたかのように、model_instance.myfile.urlとその他すべてが点灯します。
@ t-stoneが言うように、本当に欲しいのはinstance.myfile.path = 'my-filename.jpg'を設定できるようにすることですが、Djangoは現在サポートしていません。
これはあなたが探している答えではないかもしれません。ただし、ImageFileの代わりにcharfieldを使用してファイルのパスを保存できます。そのようにして、ファイルを再作成せずに、アップロードされた画像をプログラムでフィールドに関連付けることができます。
class Tweet_photos(models.Model):
upload_path='absolute path'
image=models.ImageField(upload_to=upload_path)
image_url = models.URLField(null=True, blank=True)
def save(self, *args, **kwargs):
if self.image_url:
import urllib, os
from urlparse import urlparse
file_save_dir = self.upload_path
filename = urlparse(self.image_url).path.split('/')[-1]
urllib.urlretrieve(self.image_url, os.path.join(file_save_dir, filename))
self.image = os.path.join(file_save_dir, filename)
self.image_url = ''
super(Tweet_photos, self).save()
あなたが試すことができます:
model.ImageField.path = os.path.join('/Upload', generated_image_path)
class Pin(models.Model):
"""Pin Class"""
image_link = models.CharField(max_length=255, null=True, blank=True)
image = models.ImageField(upload_to='images/', blank=True)
title = models.CharField(max_length=255, null=True, blank=True)
source_name = models.CharField(max_length=255, null=True, blank=True)
source_link = models.CharField(max_length=255, null=True, blank=True)
description = models.TextField(null=True, blank=True)
tags = models.ForeignKey(Tag, blank=True, null=True)
def __unicode__(self):
"""Unicode class."""
return unicode(self.image_link)
def save(self, *args, **kwargs):
"""Store image locally if we have a URL"""
if self.image_link and not self.image:
result = urllib.urlretrieve(self.image_link)
self.image.save(os.path.basename(self.image_link), File(open(result[0], 'r')))
self.save()
super(Pin, self).save()
Django REST_ framework およびpython Requests ライブラリを使用して、プログラムを使用して画像をDjango ImageFieldに保存できます。
次に例を示します。
import requests
def upload_image():
# PATH TO Django REST API
url = "http://127.0.0.1:8080/api/gallery/"
# MODEL FIELDS DATA
data = {'first_name': "Rajiv", 'last_name': "Sharma"}
# UPLOAD FILES THROUGH REST API
photo = open('/path/to/photo'), 'rb')
resume = open('/path/to/resume'), 'rb')
files = {'photo': photo, 'resume': resume}
request = requests.post(url, data=data, files=files)
print(request.status_code, request.reason)
ワーキング! FileSystemStorageを使用して画像を保存できます。以下の例を確認してください
def upload_pic(request):
if request.method == 'POST' and request.FILES['photo']:
photo = request.FILES['photo']
name = request.FILES['photo'].name
fs = FileSystemStorage()
##### you can update file saving location too by adding line below #####
fs.base_location = fs.base_location+'/company_coverphotos'
##################
filename = fs.save(name, photo)
uploaded_file_url = fs.url(filename)+'/company_coverphotos'
Profile.objects.filter(user=request.user).update(photo=photo)