2014-11-29 11 views
5

Basit bir soru olarak kabul ettiğim şeylere sahibim. Benim modelde böyle görünen bir models.ImageField vardır:Python Django: Bir örneğe bağlı olarak bir dosya adı nasıl yüklenir pk

class CMSDocument(BaseItem): 
    thumb = models.ImageField(upload_to= './media/',blank=True) 

Ama '.media/' + self.pk+ '.png' yüklemek istiyorum ben modelinin tasarruf yöntemi içinde alanını güncellemek için çalıştı, ama bu işe yaramazsa, 'save' çağrıldığında pk bilinmediğinden. Ayrıca burada önerildiği gibi upload_to için özel bir işlev eklemeyi denedim: Django: Any way to change "upload_to" property of FileField without resorting to magic?. Ama bu sadece alanı boş bırakır. Ne yapabilirim?

DÜZENLEME: Django 1.6

EDIT kullanın: Eğer modeline kadar beklemek zorunda

def video_embed_post_save(sender, instance=False, **kwargs):  
    document = DocumentEmbedType.objects.get(pk=instance.pk)  
    new_thumb = "media/%s.png" % (document.pk,) 
    if not document.thumb == new_thumb: 
     document.thumb = new_thumb 
     document.save() 
    ... 
+0

deneyin bu http://stackoverflow.com/questions/651949/django-access-primary-key-in-models-filefieldupload-to-location – madzohan

+0

Çok çirkin bir yaklaşım, kaydetme yönteminde, son kaydın kimliğini alır ve bunu birer birer artırır ve yeni kimlik olarak kullanır. – Ymartin

+0

hmmm, aslında bir kesmek bir bit bir post_save sinyali kullanmak için sona erdi (Ben dosya adı zaten doğru olup olmadığını, eğer ben değiştirmek ve modelini kaydetmek değilse, bu şekilde özyinelemeyle sorun alamıyorum)). Ama ben @madzohan çözümünü kontrol edeceğim. – Magda

cevap

3

birincil anahtar veritabanı tarafından atanır: Ben çok güzel olmayan bir post_save sinyali kullanılır satır db'ye kaydedilir.

Öncelikle çocuk modeline küçük resimle, iki modelin verilerinizi bölmek:

from django.db import models 

from .fields import CMSImageField 


class CMSDocument(models.Model): 
    title = models.CharField(max_length=50) 


class CMSMediaDocument(CMSDocument): 
    thumb = CMSImageField(upload_to='./media/', blank=True) 

sen yerine ImageField küçük resmi için özel bir alan kullanıyorum Gördüğünüz gibi.

Öyleyse ImageField miras FileField sınıfının pre_save fonksiyonunu geçersiz kılmak gereken bir fields.py dosyası oluşturmak: denir pre_save anda

from django.db import models 


class CMSImageField(models.ImageField): 
    def pre_save(self, model_instance, add): 

     file = super(models.FileField, self).pre_save(model_instance, add) 

     if file and not file._committed: 
      # Commit the file to storage prior to saving the model 
      file.save('%s.png' % model_instance.pk, file, save=False) 
     return file 

CMSMediaDocument CMSDocument sınıfından devraldığı için, ilerleyen PK, veritabanına zaten kaydedilir, böylece pk'yi model_instance'dan ayıklayabilirsiniz.

Kodu test ettim ve iyi çalışmalıyım.

testte kullanılan yönetici dosyası:

from django.contrib import admin 

from .models import CMSMediaDocument 

admin.site.register(CMSMediaDocument) 
İlgili konular