Django

Jak zapisać obrazek PIL w modelu, nie zapisując go wcześniej do pliku tymczasowego?

Słowem wstępu

Pisząc ostatnimi czasy portal z użyciem Django natknąłem się na parę problemów, które rozwiązać przyszło mi samemu, bo w internecie brak było gotowych recept. Takoż chciałbym jedno z takich rozwiązań umieścić tutaj, aby w przyszłości osoby mające podobny problem nie musiały się nad nim głowić, jak ja.

Zapisanie pliku przetwarzanego przez PIL w nowym obiekcie modelu, bez konieczności tworzenia plików tymczasowych

Czyli innymi słowy, jak wgrać na serwer plik, zmienić jego rozmiar, a następnie utworzyć obiekt reprezentujący go w galerii, tak aby nie trzeba było wpierw zapisywać oryginału na dysk, by Django nadało mu automatycznie jakąś nazwę pliku.

def generate_name(name, field, ext):

	"""
	Funkcja generująca nazwę dla pliku. Parametry:
	   name    nazwa pliku w systemie użytkownika
	   field   pole modelu do którego ma trafić obrazek
	   ext     docelowe rozszerzenie pliku
	"""
	i = name.rfind('.')
	if i>=0: name = name[:i]

	name = field.field.generate_filename(field.field, name)
	if not exists(MEDIA_ROOT + name + ext):
		return name + ext
	# Jeśli nazwa pliku jest zajęta, dołączamy do niej podkreślnik
	# i próbujemy dołączać kolejne liczby, aż znajdziemy nazwę,
	# która jest jeszcze wolna.

	name += '_'
	i = 0
	while exists(MEDIA_ROOT + name + str(i) + ext):

		i += 1
	return name + str(i) + ext

# Otwieramy przesłany obrazek.
img = Image.open(form.cleaned_data.get("file"))

# Konwertujemy go na wszelki wypadek (gdyby u?żytkownik wysłał np. GIFa) na RGB.
img = img.convert("RGB")
# Jeśli jego rozmiar jest za duży — zmniejszamy go odpowiednio.
w, h = img.size
if w>800 or h>800 or (w>600 and h>600):

	img.thumbnail((800, 600) if w>h else (600, 800), Image.ANTIALIAS)

# Tworzymy nowy obiekt klasy naszego modelu.
photo = Photo(author = request.user)

# Generujemy nazwę pliku,
filename = generate_name(form.cleaned_data.get("file").name, photo.file, '.jpg')

# zapisujemy obrazek…
img.save(MEDIA_ROOT + filename, "JPEG")
# …i wsadzamy do stworzonego wcześniej obiektu.
photo.file = filename


# // ewentualne ustawienie innych pól obiektu photo //


# A na koniec zapisujemy zapisujemy obiekt modelu w bazie danych.
photo.save

Ten wpis został opublikowany w kategorii Informatyka i oznaczony tagami , , , . Dodaj zakładkę do bezpośredniego odnośnika.

Dodaj komentarz

Twój adres email nie zostanie opublikowany.
Pola, których wypełnienie jest wymagane, są oznaczone symbolem *