2016-03-23 19 views
1

İki modelim var, Foto ve FotoMetadata. Foto sadece yükleme adı verilen bir özellik var, bu bir yükleme alanı. FotoMetadata'un birkaç özelliği vardır ve Foto adresinden yüklenen fotoğraftan meta veriler almalıdır. Bu, yönetici arayüzünde manuel olarak yapılabilir, ancak bunu otomatik olarak yapmak istiyorum, yani: bir fotoğraf yönetici arayüzü üzerinden yüklendiğinde, FotoMetadata otomatik olarak doldurulur. Ben yönetici sitesinde giriş yaptığındaDjango admin aracılığıyla yüklenen dosya meta verilerle popülasyon modeli

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, 
    ) 

, ben Foto ilgili bir yükleme formu var ve şudur: Benim model.py yılında

Ben Foto ve FotoMetadata dahil birkaç sınıfları iyi çalışıyor. Sorunum, hareket halindeyken FotoMetadata numaralı telefona meta veri ekleyemem. Fotoğrafı ayrıştıran ve ihtiyacım olan bilgileri içeren bir sözlük verdim. Bu işlev, GetExif adlı getexif.py adlı bir dosyada denir. Bu onun bir basitleştirilmiş versiyonu olacaktır:

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 

Yani öncelikle benim yapmaya çalışıyorum otomatik Foto bir fotoğrafı yükleyerek FotoMetadata doldurmak için admin.py bu işlevi kullanmak, ama gerçekten ben nasıl yapılacağını anlayamadım. Kimsenin bir ipucu var mı?


Düzenleme 24/03/2016

Tamam, ben admin.py yılında save_model kullanmaya çalışıyorum çok daha fazla arızaları sonra:

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) 

İşe yarayacağını ya da veriyi modele kaydetmede sorun yaşayacağımı düşündüm ama aslında bundan önce sıkışmıştım. Bu hata var:

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

GetExif işlevim dosyayı okuyamaz, ancak dosya yolu doğrudur! Tarayıcıya kopyalayıp yapıştırırsam dosyayı indirir. Adresi düzeltmek ya da iç yolu geçmek ya da gerçek dosyayı yolunun yerine işleve iletmek için bir yol bulmaya çalışıyorum. Ayrıca dosyaya GetExif() işlevinde de erişmenin farklı bir yolunu düşünüyorum. Nasıl çözüleceğine dair bir fikrin var mı?


Çözüm Yukarıda sorunu çözüldü

! FileField kaynağını okuyarak, sorunu çözen path adlı bir özellik buldum. Ayrıca birkaç değişiklik yaptım ve kod çalışıyor. admin.py de sınıf FotoAdmin, şimdi şu şekildedir:

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() 

Ben de models.py bazı özelliklerini null=True ayarlamak zorunda kaldı ve her şey olması gerektiği gibi çalışıyor.

cevap

1

Sana bir sinyal okuma post_save etkinleştirmek istediğiniz tahmin:

post_save sinyalini etkinleştirme django signals - böylece bir FOTO kaydettikten sonra bir FotoMetadata davanızın ayrıştırma photometa diğer şeyini yapmak ve oluşturmak için bir kanca var örneği.

Daha fazla, eğer fotometa başarılı olursa ya da başka herhangi bir koşulda kullanabiliyorsanız, kaydetmeden önce kaydetmek ve meta foto kaydedildikten sonra fotoyu kaydetmek için daha fazla.

+0

Bir araştırma yaptım ve 'save_model' kullanarak sonlandırdım. Ancak yüklenen dosyaya erişmek için sorun yaşıyorum. Sadece instace erişebilirim. Orijinal gönderiyi daha fazla bilgi ile düzenledim. GetExif, satır 24, – rvbarreto

+0

hata, pls kodunuzu ekleyin, –

+1

24 satır 'f = açık (foto, 'rb')' dir. Yardımın için teşekkürler, sadece sıkıştığımda bana çok yardımcı oldu. Sorunu zaten çözdüm ve çözümü gönderin! Teşekkürler! – rvbarreto