Kurs Django Podstawa – #3 – Rozszerzenie sklepu

Posted on: August 7, 2024

Kurs Django Podstawa – #3 – Rozszerzenie sklepu

Kurs Django Podstawa – #3 – Rozszerzenie sklepu

„Rozszerzenie sklepu”

Znasz już podstawy działania Django, więc dzisiaj rozbudujemy nasz sklep, dodamy kilka produktów, więcej stron i wprowadzimy dziedziczenie szablonu.

Korzystam z wcześniej stworzonego w poprzednim rozdziale (#2) serwera, na Windowsie i używam Pycharma oraz Pythona w wersji 3.10.

Zaloguj się na http://127.0.0.1:8000/admin i dodaj kilka produktów, tak jak to zrobiłeś wcześniej.

kurs-django-robot-3-im1.png

Coraz bardziej chcemy zbliżyć się do wyglądu i funkcjonalności strony, dlatego na początek zmodyfikujemy nasz folder ‘templates’ z plikami HTML i wprowadzimy trochę hierarchii i zdjęć produktów. W tym celu, podobnie jak w przypadku folderu ‘templates’, tworzymy folder ‘static’, a w nim folder ‘Sklep’ i tam pakujemy zdjęcia, które chcemy, żeby pokazały się na stronie. Jeśli pojawi się problem z nieprawidłowym wyświetlaniem zdjęć, spróbuj najpierw wyłączyć i włączyć serwer Django.

kurs-django-robot-3-im2.png

U mnie zdjęcia nazwałem w ten sposób, żeby potem je łatwiej wywołać. Będzie o tym za chwilę. Chcemy, żeby strona była łatwa w przyszłości do modyfikowania, więc staramy się automatyzować kodowo jak umiemy. Można by stworzyć kilkadziesiąt plików HTML i linków do nich, nie wspominając o funkcjach w pliku views.py, ale potem, kiedy byśmy chcieli wprowadzić jakąś zmianę w wyglądzie, trzeba by było ręcznie zmieniać kod w każdym pliku.

Dlatego stworzymy teraz jak najwięcej dziedziczenia. Stwórz 4 pliki: index.html (już go zapewne masz), produkt.html, produkty.html, szablon.html.

kurs-django-robot-3-im3.png

Szablon.html to będzie nasz… szablon strony. To co będzie się wyświetlać zawsze, chcemy zbudować taką strukturę:

kurs-django-robot-3-im4.png

Plik szablon.html prezentuje się następująco:

kurs-django-robot-3-im5.png
<!DOCTYPE html> <html lang="pl"> <head> <meta charset="UTF-8"> <title>Sklep</title> </head> <body> <h1>Witaj w naszym sklepie</h1><br> <p> <a href="/">Strona Główna</a> &nbsp;&nbsp;&nbsp; <a href="/produkty">Pokaż mi swoje towary</a> </p> {% block wszystko %}{% endblock wszystko %} </body> </html>

Wybieramy format naszej strony, ograniczmy się do tego, żeby wyświetlała bez problemu polskie znaki <html lang="pl">

W pasku wyszukiwarki zamiast adresu IP niech wyświetla się nazwa <title>Sklep</title>

Dodajemy napis zwykły, który będzie się wyświetlał wraz z dwoma napisami, które są jednocześnie odnośnikami do kolejnych plików HTML, nasz zalążek menu.

<a href="/">Strona Główna</a> link ”/” oznacza, że będzie nas odsyłać do strony index.html

potem runiczne znaki oznaczające trzy spacje &nbsp;&nbsp;&nbsp; i link do strony produkty, który będzie nam wyświetlał listę dostępnych produktów

<a href="/produkty">Pokaż mi swoje towary</a>, natomiast link “/produkty”

to skrót od http://127.0.0.1:8000/produkty

I na koniec miejsce gdzie będzie nasza zmienna w zależności od strony treść:

{% block wszystko %}{% endblock wszystko %}

Teraz plik index.html:

kurs-django-robot-3-im6.jpg
{% extends 'Sklep/szablon.html' %} {% block wszystko %} <p>Zapraszamy do przejrzenia naszej oferty</p> {% endblock wszystko %}

{% extends 'Sklep/szablon.html' %} dziedziczymy szablon z aplikacji Sklep

i definiujemy naszą Stronę Główną między blokami {% block wszystko %} oraz {% endblock wszystko %}. W tym wypadku będzie to jedno zdanie. Możesz uruchomić serwer Django i zobaczyć czy działa.

Cytując klasyka, „U mnie działa” :D

kurs-django-robot-3-im7.png

Możesz klikać w „Strona Główna” i przełączy Cię w to samo miejsce, w ten sam adres
http://127.0.0.1:8000/, jednak jak klikniesz w „Produkty”, czyli „Pokaż mi swoje towary”, wyskoczy milion błędów, że coś jest nie tak, no bo Django nie ma zdefiniowanego adresu.

kurs-django-robot-3-im8.png

Wejdź teraz w plik urls.py. Linia kodu

path('', main_page),

pewnie już istnieje jeśli robiłeś z nami kurs od początku. Dodaj natomiast adres „produkty” linijka

path('produkty', produkty, name='produkty'),

do path('produkt/', produkt, name='produkt'), wrócimy potem.
Mamy path produkty, który wywoła funkcję produkty, więc zanim się okaże, że Django wyrzuci znowu milion błędów, napiszmy funkcję produkty w pliku views.py. Funkcję „main_page” upraszczamy tylko do wywołania strony index.html oraz dodajemy nową funkcję „produkty”:

kurs-django-robot-3-im9.png
def produkty(request): produkty = Produkt.objects.all() dane = {'produkty': produkty} return render(request, 'Sklep/produkty.html', dane)

I napiszemy plik produkty.html tak, żeby wyświetlał nam w kolejności dodania wszystkie produkty z bazy danych.

kurs-django-robot-3-im10.png
{% extends 'Sklep/szablon.html' %} {% block wszystko %} <p>Dostępne od ręki:</p> {% for produkt in produkty %} <li> <a href="/produkt/{{ produkt.id }}">{{ produkt.nazwa }}</a> </li> {% endfor %} {% endblock wszystko %}

{% extends 'Sklep/szablon.html' %} - znowu dziedziczenie z szablonu i pomiędzy blokiem i endblockiem nasz kod z pętlą, która powinna Ci się kojarzyć z poprzedniego rozdziału (#2).
Z małą różnicą, że każda nazwa produktu będzie teraz linkiem do kolejnej strony (z opisem danego produktu). Na ten moment, linki są, ale nie działają, bo nie zdefiniowaliśmy ich.
{{ produkt.nazwa }} w praktyce ten adres wygląda np. tak http://127.0.0.1:8000/produkt/1, albo dla kamerki tak http://127.0.0.1:8000/produkt/2.
Jeśli to zrozumiałeś i wszystko działa, to brawo, dotarliśmy do miejsca, gdzie treściowo mamy to samo, co w poprzednim rozdziale XP.

kurs-django-robot-3-im11.png

Ale mamy to zrobione w taki sposób, że Strona Główna (na razie wygląda ubogo) i strona z produktami zależą od szablonu. Wyobraź sobie, jakbyś miał 10 stron i chciał w każdej zmienić „Witaj w naszym sklepie” na coś innego. Trzeba by zmieniać to w każdej stronce, a w ten sposób zmieniamy to tylko w szablonie. Fajne, prawda?

Teraz chcemy, żeby po kliknięciu w dany produkt wyświetlił mi się jego opis. Jak zapewne już się domyśliłeś, musimy zdefiniować adresy w urls.py, napisać funkcję w views.py oraz uzupełnić wywoływany plik HTML.

Wróć do zdjęcia wyżej, widzisz produkt „Modbus”, wiesz, że jest linkiem http://127.0.0.1:8000/produkt/1, bo w kodzie HTML jego „produkt.id” jest „1”. Chcemy przekazać tę wartość dla Django, dlatego w urls.py dopisujemy linię:

path('produkt/<id>', produkt, name='produkt'),
kurs-django-robot-3-im12.png

W ten sposób wartość <id> możemy łatwo przekazać do funkcji produkt w pliku views.py

kurs-django-robot-3-im13.png
def produkt(request, id): produkt = Produkt.objects.get(pk=id) p_id = id dane = {'produkt': produkt, 'p_id': p_id} return render(request, 'Sklep/produkt.html', dane)

W tej funkcji, oprócz standardowej wartości „request”, mamy też „id”.
Funkcja pobiera z bazy danych informację o produkcie z id=1, czyli „Modbusa”.
Zapisuję dodatkowo to id pod nową zmienną „p_id” i wysyła w paczce do pliku HTML i wywołuje ten plik, czyli produkt.html:

kurs-django-robot-3-im14.png
{% extends 'Sklep/szablon.html' %} {% block wszystko %} {% load static %} <div><img src="{% static 'Sklep/zdj'|add:p_id|add:'.png' %}" width="130" height="130" /></div> <p>nazwa: {{ produkt.nazwa }}</p> <p>opis: {{ produkt.opis }}</p> <p>cena: {{ produkt.cena }} Złotych</p> {% endblock wszystko %}

Cały czas dziedziczymy z szablonu przez {% extends 'Sklep/szablon.html' %}.
Pomiędzy blokami z treścią, wstawiamy zdjęcie {% load static %} zapakowane w pojemnik o zadanych wymiarach 130 pikseli na 130 pikseli, który wypełnia się zdjęciem znajdującym się w ścieżce 'Sklep/zdj'|add:p_id|add:'.png'.
|add:(wartość) pozwala nam bezproblemowo automatyzować ścieżkę w zależności od wartości „p_id”, czyli dla „Modbusa” wartość „1”, czyli Django bez problemu czyta ścieżkę tak: Sklep/zdj1.png i dodaje właśnie to zdjęcie.
I wyświetla opis produktu, który dostał w paczce, produktu z „id=1”, czyli „Modbusa”.

Uff, wszystko pięknie śmiga. Jeśli nie, napisz.

Podsumowanie

Moglibyśmy napisać plik HTML dla każdego produktu, jak i funkcję i adres URL, tyle że jakbyśmy chcieli wprowadzić np. dostępną ilość dla każdego produktu, musielibyśmy to zrobić wszędzie…, a tak wystarczy kilka zmian i wszystko działa!

kurs-django-robot-3-im15.png

Category: Kurs Django Podstawa