2010-04-20 7 views
42

Fotoğrafları, yüklendikleri sırada sunucudaki benzersiz bir dosya adıyla yeniden adlandırmanın en iyi yolu nedir? Her ismin sadece bir kez kullanıldığından emin olmak istiyorum. Bunu, belki de GUID ile yapabileceğiniz pinax uygulamaları var mı?django kullanarak benzersiz yükleme dosya adlarını zorla?

+0

Sen dosyaları yeniden adlandırmak için bir piton kitaplığındaki gerekir, böylece benzersiz? – Aurril

+0

evet, bu benim ortalama – zjm1126

cevap

109

kullanın uuid. Bunu modelinize bağlamak için FileField upload_to için Django documentation'a bakın. daki FileField/ImageField tanımlarken

import uuid 
import os 

def get_file_path(instance, filename): 
    ext = filename.split('.')[-1] 
    filename = "%s.%s" % (uuid.uuid4(), ext) 
    return os.path.join('uploads/logos', filename) 

Sonra, upload_to değeri olarak get_file_path belirtir: sizin models.py aşağıdaki işlev tanımlamak Örneğin

.

file = models.FileField(upload_to=get_file_path, 
         null=True, 
         blank=True, 
         verbose_name=_(u'Contact list')) 
+1

Bu, böyle yapmak için kötü bir karardır, çünkü bu alanlarda sonsuz geçişe sahip olursunuz, çünkü her geçişte farklı yükleme yollarına sahip olursunuz. –

+6

@Creotiv Bu, yükleme yolunu değiştirmiyor, dosya adını bir UUID ile değiştiriyor. Bu herhangi bir göç sorununa neden olmamalıdır. – Hybrid

+0

@Hybrid Evet, ancak her geçişte dizin yolu farklı olacak, bu nedenle geçiş sistemi bu alanın değişeceğini düşünecek. –

0

Nasıl bir mesaj özeti oluşturmak için hashlib kullanarak daha sonra Fotoğraf kaydedildi tarih/saat ile dosya adı birleştirerek ve ne olacak? Bu size benzersiz dosya isimleri vermeli.

Alternatif olarak, benzersiz dosya adları oluşturan a neat little snippet'u yeniden kullanabilirsiniz ve daha sonra bu dosyanın tam yolunu karma arama girişiniz olarak kullanabilirsiniz. Bu, dosyalarınıza eşleyebileceğiniz benzersiz sabit uzunluklu dizeler sağlar.

+0

ama aynı zamanda aynı adı nasıl yapacağım? – zjm1126

+1

Boş disk alanı miktarını karma dizeye ekleyebilirsiniz - bu, yeni bir dosya yüklediğinizde her zaman değişmelidir. –

+1

@ zjm1126 @Jon Cage, benzersiz olmanın daha muhtemel olmasını sağlamanın her türlü yolunu bulabilirsin, ama temelde her zaman bir çeşit çarpışma olasılığı var ve bu fikir o olasılığı kabul edilebilir bir miktara indirgeyecek ve Olduğunda işleyin –

5

Django 1.6.6, 1.5.9 ve 1.4.14'ten önce get_avaialable_name işlevi, altçizgi ekleyerek dosyalara otomatik olarak benzersiz bir ad verir. Yani, örneğin, bir dosya "test.jpg" ve sonra başka bir dosya, "test.jpg" sunucunuza kaydederseniz, ilk test.jpg denir ve ikincisi test_1.jpg olarak adlandırılır. bunu saklamak için sıfır bayt binlerce dosya göndererek, bir makine DDOSing için bir vektör olarak çıkıyor

Ne yazık ki, önceki binlerce dosya kontrol her biri kendi adı ne olması gerektiğini görmek için.

Eğer see in the docs olacak, yeni sistem bu sorunu çözmeye yönelik alt çizgi sonra yedi rastgele rakamlar ekler gibi.

4

Daha iyi bir yol, helpers.py dosyanızda ortak bir sınıf kullanıyor olabilir. Bu şekilde, rastgele dosya oluşturucuyu uygulamalarınızda yeniden kullanabilirsiniz.

import os 
import uuid 
from django.utils.deconstruct import deconstructible 


@deconstructible 
class RandomFileName(object): 
    def __init__(self, path): 
     self.path = os.path.join(path, "%s%s") 

    def __call__(self, _, filename): 
     # @note It's up to the validators to check if it's the correct file type in name or if one even exist. 
     extension = os.path.splitext(filename)[1] 
     return self.path % (uuid.uuid4(), extension) 

Sonra Modelinizdeki sadece yardımcı sınıfını içe: kullanmak sonra

from mymodule.helpers import RandomFileName 

Ve: En helpers.py olarak

logo = models.ImageField(upload_to=RandomFileName('logos')) 

Ref: https://coderwall.com/p/hfgoiw/give-imagefield-uploads-a-unique-name-to-avoid-file-overwrites

0

Bu cevabın yazılmasından dolayı, bunun gerçekleşmesi için artık özel bir şey yapmanıza gerek yok gibi görünüyor. Statik bir upload_to özelliğine sahip bir FileField kurarsanız, Django depolama sistemi adlandırma işlemini otomatik olarak yönetir, böylece bir çift dosya adı yüklenirse, Django iki kopya için rastgele yeni bir benzersiz dosya adı oluşturur. Django 1.10 üzerinde

eserler.