Bardzo intensywnie pracuję ostatnio nad pierwszą poważniejszą aplikacją pisaną w Django. Czegokolwiek się nie dotknę to wszystko dla mnie nowe i inne. Wczoraj przyszło mi się mierzyć z uploadem plików na serwer poprzez aplikację i wykorzystaniem jje potem w szablonach.
Zaczęło się od tego, że postanowiłam dodać moduł zarządzający treścią strony głównej, tak, żeby z panelu administracyjnego można ją było łatwo zmieniać. Projekt graficzny jest tak zrobiony, że najwygodniej dodawać jest treść w powiązaniu z ilustrującą ją grafiką. Trochę już się nauczyłam o tworzeniu modeli w Django i od razu moją uwagę przykuły ułatwienia w postaci różnych typów pól, których użycie znacznie ułatwia walidację formularzy i dodawanie danych do bazy. Wymyśliłam, że w moim przypadku najlepiej będzie użyć pola typu ImageField(), dzięki któremu łatwo można dokonać uploadu plików (ale tylko graficznych) na serwer.
Użycie tego pola i dalsze działania jakie za tym idą nie są dokładnie opisane w dokumentacji. Nawiasem mówiąc potrzebuję trochę czasu, żeby się do niej przyzwyczaić. Jednak jest w niej kilka wskazówek, resztę znalazłam w sieci i postanowiłam spisać własnie tu.
Pillow
Przede wszystkim użycie ImageField() wymaga zainstalowania pakietu Pillow w środowisku w którym tworzona jest aplikacja. Po wykonaniu komendy:
$ pip install Pillow
należy oczywiście zaktualizować plik requirements.txt:
$ pip freeze > requirements.txt
Katalog docelowy
Należy też zdefiniować katalog docelowy dla uploadowanych plików. W tym celu nie wystarczy przekazanie odpowiedniego parametru do pola ImageField()
image = models.ImageField(upload_to='home/')
Aplikacja musi wiedzieć gdzie dokładnie znajduje się ten katalog. W tym celu w pliku settings.py, który znajduje się w głównym katalogu aplikacji należy zdefiniować stałe MEDIA_URL (adres URL, pod którym dostępne będą nasze pliki ) i MEDIA_ROOT (bezwzględna ścieżka do katalogu z plikami) Janbezpieczniej zrobić to w tan sposób, oczywiście przy założeniu, że stworzymy katalog media w naszej aplikacji.
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Struktura katalogów będzie wtedy wyglądać następująco:
myproject/ manage.py application_home/ models.py <-- tu jest model wykorzystujący ImageField() media/ home/ <-- w tym miejscu będą przez ImageField() zapisywane pliki myproject/ __init__.py urls.py wsgi.py settings/ __init__.py base.py dev.py prod.py
Routing
Najwyższa pora by dodać ścieżkę do routingu, w przeciwnym razie nie da się tych plików wykorzystać w aplikacji, gdyż dostęp do nich nie będzie możliwy. Żeby to naprawić należy edytować plik url.py i dodać do niego następujące informacje:
from django.conf.urls.static import static from django.conf import settings ... ... urlpatterns = [.... ... ]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Pierwsze dwie linie to dołączenie niezbędnych pakietów. Ostatnia linia to definicji ścieżko dostępu do mediów.
Szablon
Kiedy więc dodamy już treść w naszym panelu administracyjnym i uzupełnimy ją grafiką, wybrany plik zostanie umieszczony we wskazanym katalogu a link do niego w bazie danych w odpowiedniej tabeli w polu ‘image’. Kiedy więc przyjdzie pola na wyświetlenie tej grafiki w szablonie wystarczy kod:
{% if image %} <img src="{{image.url}}" alt=""/> {% endif %}
I już działa.
z wszystkich poradników, które przeczytałam i próbowałam zaimplementować w moim projekcie ten był najlepszy i najbardziej zrozumiały :) Dziękuję bardzo!