[python] Django의 FileField를 기존 파일로 설정
디스크에 기존 파일 (예 : /folder/file.txt)과 Django에 FileField 모델 필드가 있습니다.
내가 할 때
instance.field = File(file('/folder/file.txt'))
instance.save()
파일을 file_1.txt
(다음 번 _2
에 등) 으로 다시 저장합니다 .
나는 그 이유를 이해하지만이 동작을 원하지 않습니다. 필드가 연결되기를 원하는 파일이 실제로 나를 기다리고 있다는 것을 알고 있으며 Django가이를 가리 키기를 원합니다.
어떻게?
답변
이 작업을 영구적으로 수행하려면 고유 한 FileStorage 클래스를 만들어야합니다.
import os
from django.conf import settings
from django.core.files.storage import FileSystemStorage
class MyFileStorage(FileSystemStorage):
# This method is actually defined in Storage
def get_available_name(self, name):
if self.exists(name):
os.remove(os.path.join(settings.MEDIA_ROOT, 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)
답변
instance.field.name
파일 경로로 설정 하십시오.
예
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>
답변
답변
자신의 스토리지 클래스를 작성하는 것이 옳습니다. 그러나 get_available_name
재정의하는 올바른 방법이 아닙니다.
get_available_name
Django가 동일한 이름의 파일을보고 사용 가능한 새 파일 이름을 얻으려고 할 때 호출됩니다. 이름을 바꾸는 것은 방법이 아닙니다. 그 원인은_save
. 의 주석은 _save
꽤 좋으며 os.O_EXCL
동일한 파일 이름이 이미 존재하면 OSError를 발생시키는 플래그로 작성하기 위해 파일을 쉽게 열 수 있습니다 . Django는이 오류를 포착 한 다음 호출 get_available_name
하여 새 이름을 얻습니다.
그래서 올바른 방법은 _save
flag없이 os.open () 을 재정의 하고 호출하는 것 os.O_EXCL
입니다. 수정은 아주 간단하지만 방법이 조금 길어서 여기에 붙여 넣지 않습니다. 도움이 더 필요하면 알려주세요. 🙂
답변
나는 똑같은 문제가 있었다! 그런 다음 내 모델이 그 원인을 알았습니다. 예를 들어 다음과 같은 모델을 사용했습니다.
class Tile(models.Model):
image = models.ImageField()
그런 다음 디스크의 동일한 파일을 참조하는 하나의 타일을 더 많이 갖고 싶었습니다! 그것을 해결하기 위해 찾은 방법은 내 모델 구조를 다음과 같이 변경하는 것입니다.
class Tile(models.Model):
image = models.ForeignKey(TileImage)
class TileImage(models.Model):
image = models.ImageField()
같은 파일을 DB에 더 많이 저장하려면 다른 테이블을 만들어야하기 때문입니다.
모델을 변경할 수 있기를 바라면서도 그렇게 문제를 해결할 수 있다고 생각합니다!
편집하다
또한 다음과 같은 다른 저장소를 사용할 수 있다고 생각합니다. SymlinkOrCopyStorage
http://code.welldev.org/django-storages/src/11bef0c2a410/storages/backends/symlinkorcopy.py
답변
자체 스토리지를 정의하고 FileSystemStorage에서 상속하고 OS_OPEN_FLAGS
클래스 속성 및 get_available_name()
메서드를 재정의해야 합니다 .
Django 버전 : 3.1
프로젝트 /core/files/storages/backends/local.py
import os
from django.core.files.storage import FileSystemStorage
class OverwriteStorage(FileSystemStorage):
"""
FileSystemStorage subclass that allows overwrite the already existing
files.
Be careful using this class, as user-uploaded files will overwrite
already existing files.
"""
# The combination that don't makes os.open() raise OSError if the
# file already exists before it's opened.
OS_OPEN_FLAGS = os.O_WRONLY | os.O_TRUNC | os.O_CREAT | getattr(os, 'O_BINARY', 0)
def get_available_name(self, name, max_length=None):
"""
This method will be called before starting the save process.
"""
return name
모델에서 사용자 지정 OverwriteStorage를 사용합니다.
myapp / models.py
from django.db import models
from core.files.storages.backends.local import OverwriteStorage
class MyModel(models.Model):
my_file = models.FileField(storage=OverwriteStorage())