Mam istniejący plik na dysku (powiedzmy /folder/file.txt) i pola modelu Filefield w Django.

Kiedy robię

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

Zapisuje plik jako file_1.txt (następnym razem jest _2 itp.).

Rozumiem dlaczego, ale nie chcę tego zachowania - znam plik, którego chcę, z którymi polega, z tak naprawdę czekam na mnie, a ja po prostu chcę, aby Django mogła do tego wskazać.

W jaki sposób?

90
Guard 1 grudzień 2011, 00:20

5 odpowiedzi

Najlepsza odpowiedź

Jeśli chcesz to zrobić na stałe, musisz stworzyć własną klasę filmurestorage

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

Teraz w twoim modelu używasz zmodyfikowanego MyFilestorage

from mystuff.customs import MyFileStorage

mfs = MyFileStorage()

class SomeModel(model.Model):
   my_file = model.FileField(storage=mfs)
22
Alexander Shpindler 11 czerwiec 2018, 18:18

Wystarczy ustaw instance.field.name na ścieżkę swojego pliku

Na przykład

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>
124
juliomalegria 24 luty 2014, 18:20

Spróbuj tego (Doc ):

instance.field.name = <PATH RELATIVE TO MEDIA_ROOT> 
instance.save()
14
Kjuly 23 sierpień 2013, 15:26

Dobrze pisać własną klasę pamięci masowej. Jednak get_available_name nie jest właściwą metodą zastąpienia.

get_available_name Nazywany jest, gdy Django widzi plik z tym samym nazwą i próbuje uzyskać nową dostępną nazwę pliku. To nie jest metoda, która powoduje zmianę. Metoda spowodowała, że jest _save. Komentarze w _save są całkiem dobre i można łatwo znaleźć, otwiera plik do pisania z flagą os.O_EXCL, która rzuci Oserror, jeśli już istnieje ta sama nazwa pliku. Django łapie ten błąd, a następnie połączenia get_available_name, aby uzyskać nową nazwę.

Myślę więc, że właściwy sposób jest przesadny _save i zadzwoń os.OPEN () bez flagi os.O_EXCL. Modyfikacja jest dość prosta, jednak metoda jest trochę długi, więc nie wklejam go tutaj. Powiedz mi, czy potrzebujesz więcej pomocy :)

5
x1a0 23 marzec 2012, 12:48

Miałem dokładnie ten sam problem! Wtedy zdaję sobie sprawę, że moje modele to powodowały. Przykład I Hadadade moich takich modeli:

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

Potem chciałem mieć więcej płytki odwołującej się do tego samego pliku na dysku! Sposób, w jaki stwierdził, że rozwiązałem, który zmienia moją strukturę modelu do tego:

class Tile(models.Model):
  image = models.ForeignKey(TileImage)

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

Który po tym, jak zdaję sobie sprawę, że ma więcej sensu, ponieważ jeśli chcę, aby ten sam plik był zapisywany bardziej niż jeden w moim db muszę utworzyć inny stół!

Sądzę, że też możesz rozwiązać twój problem, po prostu mając nadzieję, że możesz zmienić modele!

EDYTUJ

Myślę też, że możesz użyć innego przechowywania, takich jak na przykład: symlinkorcopystorage

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

1
Arthur Neves 30 listopad 2011, 21:31