Upload zdjęć i ich wczytywanie w aplikacji

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.

1 komentarz do wpisu “Upload zdjęć i ich wczytywanie w aplikacji”

  1. 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!

Leave a Reply

%d bloggers like this: