Ok, próbowałem już prawie wszystkiego i nie mogę tego uruchomić.
- Mam model Django z ImageField
- Mam kod, który pobiera obraz przez HTTP (przetestowany i działa)
- Obraz jest zapisywany bezpośrednio w folderze „upload_to” (upload_to to ten ustawiony w ImageField)
- Wszystko, co muszę zrobić, to powiązać już istniejącą ścieżkę pliku obrazu z ImageField
Napisałem ten kod na około 6 różnych sposobów.
Problem, na który napotykam, polega na tym, że cały kod, który piszę, powoduje następujące zachowanie: (1) Django utworzy drugi plik, (2) zmieni nazwę nowego pliku, dodając _ na końcu pliku name, a następnie (3) nie przesyłaj żadnych danych, pozostawiając w zasadzie pusty plik o zmienionej nazwie. W ścieżce „upload_to” pozostały 2 pliki, jeden rzeczywisty obraz i jeden, który jest nazwą obrazu, ale jest pusty, i oczywiście ścieżka ImageField jest ustawiona na pusty plik, który Django próbuje utworzyć .
W przypadku niejasności postaram się zilustrować:
## Image generation code runs....
/Upload
generated_image.jpg 4kb
## Attempt to set the ImageField path...
/Upload
generated_image.jpg 4kb
generated_image_.jpg 0kb
ImageField.Path = /Upload/generated_image_.jpg
Jak mogę to zrobić bez konieczności ponownego zapisywania pliku przez Django? To, co naprawdę chciałbym, to coś w tym celu ...
model.ImageField.path = generated_image_path
... ale to oczywiście nie działa.
I tak, przeszedłem przez inne pytania tutaj, takie jak to, a także dokument django na temat pliku
AKTUALIZACJA Po dalszych testach zachowuje się tak tylko, gdy działa pod Apache na Windows Server. Podczas działania pod „runserver” na XP nie wykonuje tego zachowania.
Jestem zakłopotany.
Oto kod, który działa poprawnie na XP ...
f = open(thumb_path, 'r')
model.thumbnail = File(f)
model.save()
źródło
Odpowiedzi:
Mam kod, który pobiera obraz z Internetu i przechowuje go w modelu. Ważne bity to:
Jest to trochę mylące, ponieważ zostało wyciągnięte z mojego modelu i trochę z kontekstu, ale najważniejsze części to:
Daj mi znać, jeśli masz pytania lub potrzebujesz wyjaśnień.
Edycja: dla jasności, oto model (bez wszelkich wymaganych instrukcji importu):
źródło
import urlparse
.os.path.basename(urlparse.urlparse(self.url).path)
. Dzięki za post, był pomocny.prohibited to prevent data loss due to unsaved related object 'stream'.
Super łatwe, jeśli model nie został jeszcze utworzony:
Najpierw skopiuj plik obrazu do ścieżki przesyłania (zakładane = „ścieżka /” w poniższym fragmencie).
Po drugie , użyj czegoś takiego:
przetestowany i działający w django 1.4, może działać również dla istniejącego modelu.
źródło
Tylko mała uwaga. Odpowiedź tvon działa, ale jeśli pracujesz w
open()
systemie Windows, prawdopodobnie chcesz użyć pliku'rb'
. Lubię to:lub plik zostanie obcięty przy pierwszym
0x1A
bajcie.źródło
Oto metoda, która działa dobrze i pozwala również przekonwertować plik na określony format (aby uniknąć błędu „nie można zapisać trybu P jako JPEG”):
gdzie obraz to django ImageField lub twoja_modelka_instance.image tutaj jest przykładem użycia:
Mam nadzieję że to pomoże
źródło
Ok, jeśli wszystko, co musisz zrobić, to powiązać już istniejącą ścieżkę pliku obrazu z ImageField, to rozwiązanie może być pomocne:
Cóż, jeśli tak powiem, istniejący już plik obrazu nie zostanie powiązany z ImageField, ale kopia tego pliku zostanie utworzona w katalogu upload_to jako 'imgfilename.jpg' i zostanie powiązana z ImageField.
źródło
with open('/path/to/already/existing/file', 'rb') as f:
obj.save()
Zrobiłem to, aby stworzyć własną pamięć, która po prostu nie zapisze pliku na dysku:
Następnie w moich modelach do mojego ImageField użyłem nowej niestandardowej pamięci:
źródło
Jeśli chcesz po prostu „ustawić” rzeczywistą nazwę pliku, bez ponoszenia nakładów związanych z ładowaniem i ponownym zapisywaniem pliku (!!) lub uciekaniem się do korzystania z charfield (!!!), możesz spróbować czegoś takiego - -
Spowoduje to podświetlenie twojego modelu_instance.myfile.url i wszystkich pozostałych, tak jakbyś faktycznie przesłał plik.
Jak mówi @ t-stone, tak naprawdę chcemy, aby móc ustawić instance.myfile.path = 'moja-nazwa_pliku.jpg', ale Django obecnie tego nie obsługuje.
źródło
Najprostsze rozwiązanie moim zdaniem:
źródło
Wiele z tych odpowiedzi było nieaktualnych i spędziłem wiele godzin z frustracją (jestem całkiem nowy w Django i ogólnie web dev). Znalazłem jednak tę doskonałą treść autorstwa @iambibhas: https://gist.github.com/iambibhas/5051911
źródło
To może nie być odpowiedź, której szukasz. ale możesz użyć charfield do przechowywania ścieżki do pliku zamiast ImageFile. W ten sposób możesz programowo powiązać przesłany obraz z polem bez odtwarzania pliku.
źródło
Możesz spróbować:
źródło
źródło
źródło
Pracujący! Możesz zapisać obraz za pomocą FileSystemStorage. sprawdź poniższy przykład
źródło
Możesz użyć frameworka REST Django i biblioteki żądań Pythona, aby programowo zapisać obraz w Django ImageField
Oto przykład:
źródło
Z Django 3 z modelem takim jak ten:
jeśli obraz został już przesłany, możemy bezpośrednio:
lub
źródło