2011-12-14 5 views
0

이 주제에 대한 다른 질문을 읽었지만 실제로는 내 질문에 대답하지 않습니다.Django - ImageField에서 파일 이름 바꾸기

사용자가 특정 항목을 사이트에 제출할 때 사진을 업로드 할 수있게했습니다. 모든 사용자는 여러 항목을 제출할 수 있으며 각 항목에는 하나의 그림이 있습니다.

사실, 원본 파일 이름으로 그림을 저장하고 싶지 않습니다. 항목 ID로 저장하고 싶습니다. 따라서 사용자는 ID (5) 부여 된 바나나 항목을 제출하고, 파일 이름은 내가

site_media/items/5.jpg 

하지

site_media/items/banana.jpg 

인로 저장할

banana.jpg 

경우 어떤 장고는 자동으로하고 있습니다.

이제 폼에서 POST 다중 파트 데이터를 얻을 때 이미 그림을 site_media/items/item_ID.jpg로 저장합니다. 내가 템플릿에서 필드 item.picture를 표시 할 때 그러나, 그것은

site_media/items/banana.jpg 

대신에 실제로 존재하는 파일이

site_media/items/5.jpg 

의 액세스하려고합니다. 그래서 나는 깨진 링크를 얻는다.

장고가 이미지를 링크 할 때 읽는 문자열 일 뿐이라고 기대했지만 picture.path 속성을 변경하려고 시도했지만 장고가 예외를 부여하여 다른 것으로 생각하게 만듭니다.

자연스럽게, 원래의 파일 이름으로 파일을 제거하는 대신 저장시 파일 이름을 변경하고 좋은 연습과 효율성을 위해 복사본을 새 이름으로 저장하는 솔루션이있는 것이 좋습니다.

아무도 도움이 될 수 있습니까? 고맙습니다.

모델 코드 :

item = Item.objects.create(... data from form) 
try: 
    picture = FILES['picture'] 
    print str(picture) 

    destination = open('site_media/items/'+str(item.id)+".png", 'wb+') 
    for chunk in picture.chunks(): 
     destination.write(chunk) 
    destination.close() 

    item.picture = picture 
except Exception: 
    messages.error(request, "Picture for item not loaded successfully") 

답변

1

해결책을 찾았습니다. 따라서 문제는 request.FILES에 저장된 파일 이름과 다른 파일 이름이 포함되어 있다는 것입니다.그래서 난 그냥 이런 식으로 이미지를 저장하기 전에 request.FILES 파일 이름을 변경 :

picture = FILES['picture'] 
FILES['picture'].name = str(item.id) + '.png' 

# ...save as normal 
+2

이 방법은 아직 데이터베이스에 저장되지 않습니다 새 항목에 대한 실패, 따라서 반복되는 코드로 이어질 것입니다. 'upload_to' 콜백을 사용하는 것은 그렇게 어렵지 않습니다. – sleblanc

6

당신은 이미지 필드에 upload_to 인수에 콜백을 제공 할 수

class Item(...): 
    ... 
picture = models.ImageField(
    upload_to="site_media/items/", 
    max_length=512, 
    null=True, 
    default='' 
) 

다음은 POST 양식을 처리하는 기능입니다. 지정된 함수는 저장할 현재 인스턴스를 제공받습니다. 예를 들어보십시오. this example. 이 솔루션의 문제점은 새 인스턴스에 아직 ID가없는 것일 수 있으므로 UUID과 같은 이름을 사용하여 파일 이름을 생성 할 수 있다는 것입니다. 따라서 충돌이 발생하지 않도록하려면 인스턴스를위한 하나의 파일! UUID 생성을 위해 python docs을 살펴보십시오!