2016-03-23 8 views
1

私にはFotoFotoMetadataという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.pysave_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を設定しなければならなかったし、すべてがそれが必要として働いています。

答えて

1

私はあなたがpost_save信号 読み取りを有効にしたいと思います:django signals

がpost_save信号をアクティブ化 - ので、あなたはFOTOを保存した後、あなたが他のものを行うためのフックを持って、あなたのケースの解析photometaにとFotoMetadataを作成インスタンス。

さらに、fotometaが成功した場合のみ、または他の条件を使用する場合は、pre_save信号を保存して、meta写真が保存された後にのみ保存してください。

+0

私は研究を行い、 'save_model'を使って終了しました。しかし、アップロードされたファイルにアクセスする際に問題が発生しています。私はそれをinstaceにしかアクセスできません。私は元のポストをより多くの情報で編集しました。 – rvbarreto

+0

GetExif、24行目のエラー、コードにコードを追加します。 –

+1

24行目は 'f = open(foto、 'rb')'です。あなたの助けをありがとう、私はちょうど立ち往生したときにそれは私を助けた。私はすでに問題を解決し、解決策を投稿しています!ありがとう! – rvbarreto

関連する問題