2011-11-30 2 views
62

디스크에 기존 파일 (예 : /folder/file.txt)과 Django의 FileField 모델 필드가 있습니다. 나는 그것이Django의 FileField를 기존 파일로 설정하십시오.

instance.field = File(file('/folder/file.txt')) 
instance.save() 

할 때

file_1.txt로 파일 (이 _2의 다음 번 등) 재 - 저장합니다.

필자는 이유를 이해하지만이 동작을 원하지 않는다. 필자는 필자가 필드를 연관시키고 자하는 파일이 실제로 나를 기다리고 있다는 것을 알고 있으며, 장고가 가리 키기를 원한다.

어떻게?

+1

확실하지 :

class Document(models.Model): file = FileField(upload_to=get_document_path) description = CharField(max_length=100) doc = Document() doc.file.name = 'path/to/file' # must be relative to MEDIA_ROOT doc.file <FieldFile: path/to/file> 

+0

물론 그렇습니다. 하위 클래스를 만들고 param을 추가해야하는 것처럼 보입니다. 나는이 단순한 작업을 위해 여분의 테이블을 생성하기 위해 준비하지 않았다. – Guard

+0

파일을 다른 위치에 놓고이 경로로 필드를 만든 다음 저장 한 다음 upload_to 대상에 파일을 가지고있다. – benjaoming

답변

18

FileStorage 클래스

from django.core.files.storage import FileSystemStorage 

class MyFileStorage(FileSystemStorage): 

    # This method is actually defined in Storage 
    def get_available_name(self, name): 
     return name # simply returns the name passed 

이제 모델에서 다음을 사용합니다. 수정 된 MyFileStorage

from mystuff.customs import MyFileStorage 

mfs = MyFileStorage() 

class SomeModel(model.Model): 
    my_file = model.FileField(storage=mfs) 
+0

아, 유망 해 보인다. FileField의 코드는 다소 직관적이지 않습니다 – Guard

+0

하지만 ... 요청에 따라 저장소를 변경할 수 있습니다 (예 : instance.field.storage = mfs; instance.field.save (name, file); 내 코드의 다른 지점에서 수행하지 않습니다. – Guard

+2

아니요, 저장소 엔진이 모델에 연결되어 있기 때문입니다. 단순히 파일 경로를'FilePathField' 또는 간단히 일반 텍스트로 저장하여이 모든 것을 피할 수 있습니다. –

0

나는 똑같은 문제가있었습니다! 그때 내 모델이 그 원인을 알고있었습니다. 예를 들면 다음과 같습니다.

class Tile(models.Model): 
    image = models.ImageField() 

그런 다음 디스크에서 동일한 파일을 참조하는 하나의 타일을 더 갖고 싶었습니다. 나는 그것을 해결하기 위해 찾은 방법이 내 모델 구조를 변경했다 :

내가 같은 파일을 원하는 경우 내 DB에 두 개 이상의 저장되어 있기 때문에 즉, 더 의미를 실현 한 후 I가 가지고
class Tile(models.Model): 
    image = models.ForeignKey(TileImage) 

class TileImage(models.Model): 
    image = models.ImageField() 

그것을 위해 다른 테이블을 만드십시오!

나는 당신도 당신의 모델을 바꿀 수 있기를 바랄 뿐이다.

편집 또한 당신이 예를 들어 다음과 같이 서로 다른 스토리지를 사용할 수 있습니다 생각

: SymlinkOrCopyStorage 영구적으로이 작업을 수행하려면, 당신이 당신의 자신을 만들 필요가

http://code.welldev.org/django-storages/src/11bef0c2a410/storages/backends/symlinkorcopy.py

+0

은 내 경우가 아니라 귀하의 경우에 의미가 있습니다. 나는 그것이 여러 번 참조되기를 원하지 않는다. 파일을 참조하는 객체를 만든 다음 다른 attrs에 오류가 있음을 알고 생성 양식을 다시 엽니 다. 그것의 resubmission에 나는 디스크 – Guard

+0

에 이미 저장되어있는 파일을 풀고 싶지 않기 때문에 당신이 나의 접근법을 사용할 수 있다고 생각합니다! 그 파일을 보유 할 테이블 FormFile을 가지고 있기 때문에! Form 테이블에서 해당 파일에 대해 FK를 사용하게됩니다! 그래서 당신은 같은 파일에 대한 새로운 양식을 변경/생성 할 수 있습니다! (btw 내 주요 예에서 FK의 순서를 변경 중입니다) –

+0

게시물에 도메인 (모델)을 게시하려면! 나도 더 나은 이데아를 가질 수있다! –

4

고유 한 스토리지 클래스를 작성하는 것이 좋습니다. 그러나 get_available_name은 올바른 재정의 방법이 아닙니다.

get_available_name Django는 동일한 이름의 파일을보고 새 파일 이름을 얻으려고 할 때 호출됩니다. 이름을 바꾸는 방법은 아닙니다. 메서드가 발생했습니다 _save입니다. _save에있는 주석은 꽤 괜찮습니다. 동일한 파일 이름이 이미 존재하는 경우 OSError를 던질 플래그 os.O_EXCL으로 작성하기 위해 파일을 쉽게 열어 볼 수 있습니다. Django가이 오류를 잡으면 get_available_name을 호출하여 새로운 이름을 얻습니다.

올바른 방법은 _save을 재정의하고 플래그 os.O_EXCL없이 os.open()을 호출하는 것입니다. 수정은 아주 간단하지만 방법이 길기 때문에 여기에 붙여 넣지는 않습니다.도움이 더 :)

+0

복사해야하는 코드가 50 줄이므로 상당히 나쁩니다. get_available_name을 재정의하는 것이 미래에 장고의 새로운 버전으로 업그레이드하는 것보다 더 고립되고, 더 짧고 훨씬 안전 해 보인다. –

+1

get_available_name을 단지 오버 라이딩하는 문제는 같은 이름의 파일을 업로드 할 때 서버가 무한 루프에 빠지다. '_save'는 파일 이름을 검사하고 새로운 것을 얻기로 결정했기 때문에'get_available_name'은 여전히 ​​중복 된 것을 반환합니다. 따라서 둘 다 재정의해야합니다. – x1a0

+1

죄송합니다. 우리는 두 가지 질문으로이 토론을하고 있습니다. 그러나 지금은 약간 다르다는 것을 알았습니다.) 그래서이 질문에 맞았습니다. 여러분은 이것에 있습니다. –

83

그냥 파일의 경로로 instance.field.name 설정이 필요하면 말해

예를 들어, 당신은 당신이 장고를 수정하거나`FileField`를 서브 클래 싱하지 않고 원하는 것을 얻을 수

instance.field.name = <PATH RELATIVE TO MEDIA_ROOT> 
instance.save() 
+11

'MEDIA_ROOT'의 상대 경로, 즉 입니다. – mgalgs

+6

이 예제에서는'doc.file = 'path/to/file'을 그냥 쓸 수 있다고 생각합니다. –

7

이 ( doc)하려고합니다. `FileField`가 저장 될 때마다, 파일의 새로운 복사본이 생성됩니다. 이것을 피하기위한 옵션을 추가하는 것은 상당히 간단합니다.
관련 문제