私にはFoto
とFotoMetadata
という2つのモデルがあります。 Foto
には、uploadという1つのプロパティがあります。これはアップロードフィールドです。 FotoMetadata
にはいくつかのプロパティがあり、Foto
にアップロードされた写真からメタデータを受け取る必要があります。これは管理インターフェースで手動で行うことができますが、管理インターフェースから写真をアップロードすると自動的にFotoMetadata
が入力されます。私はadminサイトにログインするとdjangoの管理者からアップロードされたファイルのメタデータをモデルに埋め込みます
class Foto(models.Model):
upload = models.FileField(upload_to="fotos")
def __str__(self):
return '%s' %(self.upload)
class FotoMetadata(models.Model):
image_formats = (
('RAW', 'RAW'),
('JPG', 'JPG'),
)
date = models.DateTimeField()
camera = models.ForeignKey(Camera, on_delete=models.PROTECT)
format = models.CharField(max_length=8, choices=image_formats)
exposure = models.CharField(max_length=8)
fnumber = models.CharField(max_length=8)
iso = models.IntegerField()
foto = models.OneToOneField(
Foto,
on_delete=models.CASCADE,
primary_key=True,
)
が、私はFoto
に関連アップロードフォームがあり、これは次のようになります。私のmodel.pyで
は私が写真とFotoMetadataを含め、いくつかのクラスを持っていますうまく動作します。私の問題は、外出先でFotoMetadata
にメタデータを挿入できないことです。私は写真を解析し、私に必要な情報の辞書を私に与える機能を作った。この関数はGetExifと呼ばれ、getexif.pyというファイルにあります。これは、それの簡易版になります。
def GetExif(foto):
# Open image file for reading (binary mode)
f = open(foto, 'rb')
# Parse file
...
<parsing code>
...
f.close()
#create dictionary to receive data
meta={}
meta['date'] = str(tags['EXIF DateTimeOriginal'].values)
meta['fnumber'] = str(tags['EXIF FNumber'])
meta['exposure'] = str(tags['EXIF ExposureTime'])
meta['iso'] = str(tags['EXIF ISOSpeedRatings'])
meta['camera'] =str(tags['Image Model'].values)
return meta
だから、基本的に、私がやろうとしていることは、自動的にFoto
で写真をアップロードFotoMetadata
を移入するadmin.pyでこの関数を使用しているが、実際にIそれを作る方法を理解できませんでした。誰かが手掛かりを持っていますか?
編集24/03/2016
[OK]を、もっとたくさんの失敗の後、私はadmin.pyにsave_modelを使用しようとしている:
from django.contrib import admin
from .models import Autor, Camera, Lente, Foto, FotoMetadata
from fotomanager.local.getexif import GetExif
admin.site.register(Autor)
admin.site.register(Camera)
admin.site.register(Lente)
admin.site.register(FotoMetadata)
class FotoAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
# populate the model
obj.save()
# get metadata
metadados = GetExif(obj.upload.url)
# Create instance of FotoMetadata
fotometa = FotoMetadata()
# FotoMetadata.id = Foto.id
fotometa.foto = obj.pk
# save exposure
fotometa.exposure = metadados['exposure']
admin.site.register(Foto, FotoAdmin)
私はそれがうまくいくと思った、あるいはモデルにデータを保存するのに問題があるかもしれないが、実際にはこれの前に突っ込んでしまった。このエラーが発生しました:
Exception Type: FileNotFoundError Exception Value:
[Errno 2] No such file or directory: ' http://127.0.0.1:8000/media/fotos/IMG_8628.CR2 ' Exception Location: /home/ricardo/Desenvolvimento/fotosite/fotomanager/local/getexif.py in GetExif, line 24
My GetExif関数はファイルを読み取ることができませんが、ファイルパスは正しいです!コピーしてブラウザに貼り付けると、ファイルがダウンロードされます。私はアドレスを修正するか、内部パスを渡すか、パスの代わりに関数に実ファイルを渡す方法を見つけようとしています。私はまた、GetExif()関数でファイルにアクセスする別の方法についても考えています。どのようにそれを解決するための任意のアイデア?
ソリューション
私は、上記の問題を解決! FileFieldソースを読むと、問題を解決するpath
というプロパティが見つかりました。私はまたいくつかの変更を行い、コードが動作しています。 admin.pyでクラスFotoAdminは、今、このようなものです:
class FotoAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
# populate the model
obj.save()
# get metadata
metadados = GetExif(obj.upload.path)
# Create instance of FotoMetadata
fotometa = FotoMetadata()
# FotoMetadata.id = Foto.id
fotometa.foto = obj
# set and save exposure
fotometa.exposure = metadados['exposure']
fotometa.save()
私もmodels.pyにいくつかのプロパティでnull=True
を設定しなければならなかったし、すべてがそれが必要として働いています。
私は研究を行い、 'save_model'を使って終了しました。しかし、アップロードされたファイルにアクセスする際に問題が発生しています。私はそれをinstaceにしかアクセスできません。私は元のポストをより多くの情報で編集しました。 – rvbarreto
GetExif、24行目のエラー、コードにコードを追加します。 –
24行目は 'f = open(foto、 'rb')'です。あなたの助けをありがとう、私はちょうど立ち往生したときにそれは私を助けた。私はすでに問題を解決し、解決策を投稿しています!ありがとう! – rvbarreto