2010-04-20 3 views
42

django를 사용하여 업로드 할 때 서버의 고유 한 파일 이름으로 사진의 이름을 바꾸는 가장 좋은 방법은 무엇입니까? 각 이름이 한 번만 사용되도록하고 싶습니다. GUID를 사용하여이를 수행 할 수있는 핀턱 앱이 있습니까?django를 사용하여 고유 한 업로드 파일 이름을 적용 하시겠습니까?

+0

파일 이름을 바꾸려면 파이썬 라이브러리가 필요하므로 고유합니다. – Aurril

+0

예, 내 뜻은 – zjm1126

답변

109

uuid를 사용하십시오. 이를 모델에 묶으려면 FileField upload_to의 경우 Django documentation을 참조하십시오. 귀하 및 FileField/ImageField 정의시

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) 

그런 다음 upload_toget_file_path 값을 지정하여 models.py 다음 함수를 정의하는 예를 들면

.

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

이것은 잘못된 결정이며, 이렇게하면이 필드에서 무한한 마이그레이션을하게되므로 원인에 따라 업로드 경로가 달라질 수 있습니다. –

+6

@Creotiv 이것은 업로드 경로를 변경하지 않고 파일 이름을 UUID로 바꿉니다. 이로 인해 마이그레이션 문제가 발생하지 않아야합니다. – Hybrid

+0

@Hybrid 그래,하지만 모든 마이그레이션에서 디렉토리 경로가 달라져서 마이그레이션 시스템이 해당 필드가 변경된 것으로 생각할 것입니다. –

0

사진을 업로드 한 날짜/시간과 파일 이름을 연결 한 다음 hashlib을 사용하여 메시지 요약을 만드는 것은 어떨까요? 그렇게하면 고유 한 파일 이름을 얻을 수 있습니다.

또는 a neat little snippet을 다시 사용하여 고유 한 파일 이름을 만든 다음 해당 파일의 전체 경로를 해시 호출의 입력으로 사용할 수 있습니다. 이렇게하면 파일에 매핑 할 수있는 고유 한 상수 길이 문자열이 제공됩니다.

+0

이지만 같은 시간에 같은 이름을 어떻게 수행할까요? – zjm1126

+1

해시 문자열에 사용 가능한 디스크 공간을 추가 할 수 있습니다. 새 파일을 업로드 할 때 항상 변경되어야합니다. –

+1

@ zjm1126 @ 존 케이지 (Jon Cage) 당신은 그것을 독특하고 더 많이 만들 수있는 모든 종류의 방법을 고안 할 수 있지만, 기본적으로 항상 어떤 종류의 충돌 가능성이 있습니다. 아이디어는 그 확률을 수용 가능한 양으로 줄이는 것입니다. 일어날 때 처리하십시오 –

5

Django 1.6.6, 1.5.9 및 1.4.14 이전 버전의 get_avaialable_name 함수는 밑줄을 추가하여 파일에 고유 한 이름을 자동으로 지정합니다. 예를 들어 하나의 파일 "test.jpg"를 저장 한 다음 다른 파일 "test.jpg"를 서버에 저장하면 첫 번째 파일은 test.jpg가되고 두 ​​번째 파일은 test_1.jpg가됩니다.

아아, 기계를 DDOSing하기위한 벡터 인 것으로 밝혀졌습니다. 수천 개의 이전 파일을 검사하여 이름이 무엇인지 확인하는 수천 개의 0 바이트 파일을 저장합니다.

see in the docs처럼 새 시스템은이 문제를 해결하기 위해 밑줄 뒤에 7 자리의 임의의 숫자를 추가합니다.

4

더 나은 방법은 helpers.py에서 공통 클래스를 사용하는 것입니다. 이렇게하면 앱 전체에서 임의의 파일 생성기를 재사용 할 수 있습니다.

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) 

그리고 모델에 바로 헬퍼 클래스를 가져옵니다 : 사용 후

from mymodule.helpers import RandomFileName 

을 그리고 : 당신의 helpers.py에서

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

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

0

이 답변을 쓰는 ​​시점에서 더 이상 특별한 일을 할 필요가없는 것처럼 보입니다. 정적 upload_to 속성을 사용하여 FileField를 설정하면 Django 스토리지 시스템이 자동으로 이름을 관리하여 중복 된 파일 이름이 업로드되면 Django는 복제본에 대해 새로운 고유 한 파일 이름을 무작위로 생성합니다.

장고 1.10에서 작동합니다.

관련 문제