7.2. Czat 2
Dodawanie, edycja, usuwanie czy przeglądanie danych zgromadzonych w bazie są typowymi czynnościami w aplikacjach internetowych określanymi angielskim skrótem CRUD. Utworzony w scenariuszu Czat 1 kod ilustruje krok po korku obsługę żądań GET i POST oraz niektórych operacji CRUD (odczyt i dodawanie danych).
Django zawiera gotowe rozwiązania, które skracają realizację typowych zadań eliminując również potencjalne błędy. W tym scenariuszu poznasz m. in. widoki wbudowane oparte na klasach służące zarządzaniu użytkownikami oraz odczytywaniu, dodawaniu, edytowaniu i usuwaniu danych.
Uwaga
Wymagane oprogramowanie:
Środowisko wirtualne Pythona v. 3.x
Django v. 5.1.x
Opcjonalnie: interpreter bazy SQLite3
Zalecana wiedza i umiejętności:
Zrealizowany scenariusz Czat 1.
7.2.1. Środowisko pracy
Do pracy potrzebujemy katalogu z utworzonym środowiskiem wirtualnym Pythona, w którym zainstalowano
pakiet Django. Możemy wykorzystać katalog projekty_django ze scenariusza Czat 1
lub przygotować ten katalog od początku zgodnie z instrukcjami (zob. Czat 1 – Środowisko pracy
Następnie w katalogu projekty_django tworzymy nowy projekt o nazwie czat2:
(.venv) ~/projekty_django$ django-admin startproject czat2
(.venv) ~/projekty_django$ cd czat2
7.2.2. Lista użytkowników
Na początku zajmiemy się obsługą użytkowników, która realizowana będzie przez osobną aplikację.
W katalogu projekty_django/czat2 tworzymy aplikację o nazwie users:
(.venv) ~/projekty_django/czat2$ python manage.py startapp users
Następnie tworzymy plik czat2/users/urls.py, w którym umieszczamy poniższy kod:
1from django.urls import path
2from . import views
3
4app_name = 'users' # przestrzeń nazw aplikacji
5urlpatterns = [
6 path('', views.index, name='index'),
7]
W liście urlpatterns definiujemy powiązanie między domyślnym adresem URL aplikacji i widokiem index.
Dalej w pliku czat2/users/views.py umieszczamy kod widoku, czyli funkcję index():
1from django.contrib.auth.models import User
2from django.shortcuts import render
3
4def index(request):
5 users = User.objects.all()
6 kontekst = {'users': users}
7 return render(request, 'users/index.html', kontekst)
Zadaniem widoku jest pobranie z bazy danych wszystkich użytkowników i przekazanie ich do szablonu.
Kolejnym krokiem jest utworzenie odpowiednich podkatalogów i umieszczenie kodu szablonu
w pliku czat2/users/templates/users/index.html:
1<!-- templates/users/index.html -->
2<!DOCTYPE html>
3<html lang="pl">
4<head>
5 <meta charset="UTF-8">
6 <title>Lista użytkowników</title>
7</head>
8<body>
9 <h1>Lista użytkowników</h1>
10 <ul>
11 {% if users %}
12 {% for user in users %}
13 <li>{{ user.username }}</li>
14 {% endfor %}
15 {% else %}
16 <p>Brak użytkowników!</p>
17 {% endif %}
18 </ul>
19
20 {% if user.is_authenticated %}
21 <p>Jesteś już zalogowany jako {{ user.username }}.</p>
22 {% else %}
23 <p><a href="{% url 'users:rejestruj' %}">Utwórz konto</a></p>
24 {% endif %}
25</body>
26</html>
W pierwszym tagu warunkowym {% if users %} sprawdzamy, czy lista users zawiera jakichś użytkowników.
Jeżeli tak, za pomocą tagu for wypiszemy ich nazwy, w przeciwnym razie komunikat „Brak użytkowników”.
W drugim tagu warunkowym {% if user.is_authenticated %} sprawdzamy, czy jakiś użytkownik jest zalogowany.
Jeżeli tak, wypiszemy komunikat „Jesteś już zalogowany jako …”, w przeciwnym razie wypisany zostanie
link do utworzenia konta.
7.2.3. Dodawanie użytkowników
Użytkownicy będą mogli samodzielnie zakładać konta, logować i wylogowywać się. Inaczej niż w aplikacji Czat 1 zadania te zrealizujemy za pomocą tzw. widoków wbudowanych opartych na klasach (ang. class-based generic views).
W pliku czat2/users/urls.py importujemy formularz tworzenia użytkownika (UserCreationForm)
oraz wbudowany widok przeznaczony do dodawania danych (CreateView):
1from django.urls import path
2from . import views
3from django.contrib.auth.forms import UserCreationForm
4from django.views.generic import CreateView
W tym samym pliku czat2/users/urls.py w liście urlpatterns definiujemy adres URL /rejestruj,
który obsługiwany będzie przez zaimportowany wyżej widok wywołany jako funkcja.
10 path('rejestruj/', CreateView.as_view(
11 template_name='users/rejestruj.html',
12 form_class=UserCreationForm,
13 success_url='/users/'),
14 name="rejestruj"),
Widok CreateView otrzymuje trzy argumenty, które przekazujemy do metody as_view():
template_name– nazwa pliku szablonu, w którym umieścimy formularz tworzenia użytkownika,
form_class– nazwa klasy definiującej formularz tworzenia użytkownika,
success_url– adres, na który nastąpi przekierowanie w przypadku braku błędów, np. po udanej rejestracji.
Zawartość szablonu umieszczamy w pliku templates/users/rejestruj.html:
1<!-- templates/users/rejestruj.html -->
2<!DOCTYPE html>
3<html lang="pl">
4<head>
5 <meta charset="UTF-8">
6 <title>Rejestracja użytkownika</title>
7</head>
8<body>
9 <h1>Rejestracja użytkownika</h1>
10 {% if user.is_authenticated %}
11 <p>Jesteś już zalogowany jako {{ user.username }}.</p>
12 {% else %}
13 <form method="POST">
14 {% csrf_token %}
15 {{ form.as_p }}
16 <button type="submit">Zarejestruj</button>
17 </form>
18 {% endif %}
19 </body>
20</html>
Jeżeli zalogowany użytkownik wejdzie na stronę, zobaczy komunikat „Jesteś już zalogowany jako …”, natomiast użytkownik niezalogowany zobaczy formularz zakładania konta.
7.2.3.1. Ćwiczenie
W ustawieniach projektu czat2:
zarejestruj aplikację users,
ustaw polską wersję językową,
zlokalizuj datę i czas.
W konfiguracji adresów URL projektu powiąż adres URL
users/z adresami URL aplikacji users.Uruchom serwer deweloperski i w przeglądarce wejdź na adres 127.0.0.1:8000/users/.
Dodaj użytkowników adam i ewa z hasłem zaq1@WSX.
7.2.4. Wy(logowanie)
Na początku pliku czat2/users/urls.py aplikacji dopisujemy wymagany import:
5from django.contrib.auth.views import LoginView, LogoutView
– a następnie uzupełniamy listę urlpatterns:
15 path('loguj/', LoginView.as_view(
16 template_name='users/loguj.html',
17 next_page='users:index'),
18 name='loguj'),
19 path('wyloguj/', LogoutView.as_view(
20 next_page='users:index'),
21 name='wyloguj'),
Z adresami /loguj i /wyloguj wiążemy wbudowane w Django widoki LoginView i LogoutView
zaimportowane z modułu django.contrib.auth.views. Widoki wywołujemy jako funkcje za pomocą metody as_view(),
która otrzymuje argumenty:
template_name– nazwę pliku szablonu, w którym umieścimy formularz logowania użytkownika,
next_page– nazwa adresu URL, na który przekierowujemy użytkownika po zalogowaniu lub wylogowaniu się.
Informacja
Adresy, na które zostaje przekierowany użytkownik po zalogowaniu lub wylogowaniu za pomocą widoków wbudowanych,
mogą być określane również za pomocą stałych LOGIN_REDIRECT_URL i LOGOUT_REDIRECT_URL zdefiniowanych w pliku
ustawień projektu. W naszym przypadku na końcu pliku czat2/settings.py moglibyśmy umieścić kod:
LOGIN_REDIRECT_URL = '/users/'
LOGOUT_REDIRECT_URL = '/users/'
Logowanie wymaga szablonu, który tworzymy i zapisujemy w pliku templates/users/loguj.html:
1<!-- templates/users/loguj.html -->
2<!DOCTYPE html>
3<html lang="pl">
4<head>
5 <meta charset="UTF-8">
6 <title>Logowanie użytkownika</title>
7</head>
8<body>
9 <h1>Logowanie użytkownika</h1>
10 {% if user.is_authenticated %}
11 <p>Jesteś już zalogowany jako {{ user.username }}.</p>
12 <form method="POST" action="{% url 'users:wyloguj' %}">
13 {% csrf_token %}
14 <button type="submit">Wyloguj</button>
15 </form>
16 {% else %}
17 <form method="POST">
18 {% csrf_token %}
19 {{ form.as_p }}
20 <button type="submit">Zaloguj</button>
21 </form>
22 {% endif %}
23</body>
24</html>
7.2.4.1. Ćwiczenie
W szablonie
users/index.htmlumieść linki służące do logowania i wylogowania. Użyj metody POST.
Zaloguj się jako użytkownik.
Wyloguj się.
7.2.5. Wiadomości
Chcemy, by zalogowani użytkownicy mogli przeglądać wiadomości wszystkich użytkowników, zmieniać, usuwać i dodawać własne. Podobnie jak w przypadku obsługi użytkowników, w realizacji tych zadań również użyjemy widoków wbudowanych opartych na klasach.
Informacja
Django oferuje wbudowane widoki przeznaczone do typowych operacji:
DetailView i ListView – (ang. generic display view) widoki przeznaczone do prezentowania szczegółów i listy danych;
FormView, CreateView, UpdateView i DeleteView – (ang. generic editing views) widoki przeznaczone do wyświetlania formularzy ogólnych, w szczególności służących dodawaniu, uaktualnianiu, usuwaniu obiektów (danych).
Początek pracy będzie podobny jak w przypadku aplikacji „Czat 1”:
W katalogu
projekty_django/czat2tworzymy aplikację czat.Rejestrujemy aplikację w projekcie.
Dodajemy model danych, tj. klasę
Wiadomościw plikumodels.py:
1from django.contrib.auth.models import User
2from django.db import models
3from django.utils import timezone
4
5
6class Wiadomosc(models.Model):
7
8 """Klasa reprezentująca wiadomość w systemie"""
9 tekst = models.CharField('treść wiadomości', max_length=250)
10 data_pub = models.DateTimeField('data publikacji', default=timezone.now)
11 autor = models.ForeignKey(User, on_delete=models.CASCADE)
12
13 class Meta: # ustawienia dodatkowe
14 verbose_name = 'wiadomość' # nazwa obiektu w języku polskim
15 verbose_name_plural = 'wiadomości' # nazwa obiektów w l.m.
16 ordering = ['data_pub'] # domyślne porządkowanie danych
17
18 def __str__(self):
19 return self.tekst # "autoprezentacja"
Ostrzeżenie
W porównaniu do modelu użytego w aplikacji Czat 1 w definicji pola data_pub argument auto_now_add=True
zastępujemy default=timezone.now, aby użytkownik mógł modyfikować datę dodania wiadomości w formularzu.
Przygotowujemy migrację dla aplikacji „czat” i ją wykonujemy.
Wskazówka
Dla przypomnienia poniżej kolejne polecenia wydawane w aktywnym środowisku wirtualnym
w katalogu projekty_django/czat2:
(.venv) ~/projekty_django/czat2$ python manage.py startapp czat
(.venv) ~/projekty_django/czat2$ python manage.py makemigrations czat
(.venv) ~/projekty_django/czat2$ python manage.py migrate
(.venv) ~/projekty_django/czat2$ python manage.py check
Ostatnie wydane polecenie sprawdza poprawność wykonanych czynności i powinno zwrócić komunikat System check identified no issues (0 silenced).
Jeżeli masz problem z wykonaniem powyższych czynności, zajrzyj do punktów 8.1.2 – 8.1.3 ze scenariusza Czat 1.
7.2.6. Strona główna
Chcemy, żeby aplikacja czat obsługiwała żądanie wyświetlenia strony głównej. W tym celu tworzymy nowy
plik projekty_django/czat/urls.py i uzupełniamy go kodem:
1from django.urls import path
2from . import views # import widoków aplikacji
3
4app_name = 'czat' # przestrzeń nazw aplikacji
5urlpatterns = [
6 path('', views.index, name='index'),
7]
Jak widać adres domyślny aplikacji '' obsługiwany ma być przez widok index. Zatem w pliku czat/views.py
umieszczamy kod:
1from django.shortcuts import render
2
3
4def index(request):
5 return render(request, 'czat/index.html')
Następnie musimy dodać szablon, który umieszczamy w pliku templates/czat/index.html:
1<!-- templates/czat/index.html -->
2<!DOCTYPE html>
3<html lang="pl">
4<head>
5 <meta charset="UTF-8">
6 <title>Aplikacja Czat 2</title>
7</head>
8<body>
9 <h1>Aplikacja Czat 2</h1>
10 <nav>
11 <a href="{% url 'czat:index' %}">Strona główna</a> •
12 <a href="{% url 'users:loguj' %}">Zaloguj się</a> •
13 <a href="{% url 'users:rejestruj' %}">Utwórz konto</a> •
14 <a href="{% url 'czat:lista' %}">Lista wiadomości</a>
15 </nav>
16</body>
17</html>
Na koniec włączamy konfigurację URL aplikacji do konfiguracji projektu, czyli w pliku
projekty_django/czat2/urls.py lista urlpatterns powinna wyglądać następująco:
urlpatterns = [
path('', include('czat.urls')),
path('czat/', include('czat.urls')),
path('users/', include('users.urls')),
path('admin/', admin.site.urls),
]
7.2.6.1. Ćwiczenie
Uruchamiamy serwer deweloperski i otwieramy w przeglądarce adres domyślny
127.0.0.1:8000, powinniśmy zobaczyć stronę wygenerowaną na podstawie dodanego szablonu:
7.2.7. Lista wiadomości
W pliku projekty_django/czat/urls.py uzupełniamy importy i dodajemy definicję adresu URL:
1from django.urls import path
2from . import views # import widoków aplikacji
3from django.contrib.auth.decorators import login_required
4from .models import Wiadomosc
5
6app_name = 'czat' # przestrzeń nazw aplikacji
7urlpatterns = [
8 path('', views.index, name='index'),
9 path('lista/', login_required(views.ListaWiadomosci.as_view()), name='lista'),
Adres lista/ będzie obsługiwany przez klasę zdefiniowaną w pliku views.py, którą wywołujemy jako funkcję:
views.ListaWiadomosci.as_view(). Wywołanie umieszczamy w funkcji login_required(), aby wiadomości mogli
oglądać tylko zalogowani użytkownicy.
Adres, na który przekierowany zostanie użytkownik, jeżeli nie będzie zalogowany, definiujemy
na końcu pliku czat2/settings.py w stałej LOGIN_URL:
LOGIN_URL = '/users/loguj'
Do pliku czat/views.py dodajemy wymagane do wszystkich operacji CRUD importy
oraz kod klasy ListaWiadomosci:
1from django.shortcuts import render
2from django.views.generic import ListView, DeleteView
3from django.views.generic.edit import CreateView, UpdateView
4from .models import Wiadomosc
5from django.utils import timezone
6from django.contrib import messages
7
8
9def index(request):
10 return render(request, 'czat/index.html')
11
12
13class ListaWiadomosci(ListView):
14 model = Wiadomosc
15 context_object_name = 'wiadomosci'
16 paginate_by = 2
17
Klasę ListaWiadomosci tworzymy na podstawie wbudowanej wbudowanej klasy ListView
i dostosowujemy jej właściwości:
model– podajemy model, którego dane zostaną pobrane z bazy;context_object_name– zmieniamy domyślną nazwę (object_list) listy obiektów przekazanych do szablonu;paginate_by– określamy ilość obiektów wyświetlanych na stronie.
7.2.7.1. Szablon
Potrzebujemy szablonu, którego klasa ListView szuka pod domyślną nazwą <nazwa modelu>_list.html,
czyli w naszym przypadku tworzymy plik templates/czat/wiadomosc_list.html:
1<!-- templates/czat/wiadomosc_list.html -->
2<!DOCTYPE html>
3<html lang="pl">
4<head>
5 <meta charset="utf-8">
6 <title>Lista wiadomości</title>
7</head>
8<body>
9 <h1>Lista wiadomości</h1>
10 <ol>
11 {% for wiadomosc in wiadomosci %}
12 <li>
13 <strong>{{ wiadomosc.autor.username }}</strong> ({{ wiadomosc.data_pub }}):
14 <br> {{ wiadomosc.tekst }}
15 </li>
16 {% endfor %}
17 </ol>
18
19 {% if is_paginated %}
20 <p>
21 {% if page_obj.has_previous %}
22 <a href="?page={{ page_obj.previous_page_number }}">Poprzednie</a>
23 {% endif %}
24
25 Strona {{ page_obj.number }} z {{ page_obj.paginator.num_pages }}.
26
27 {% if page_obj.has_next %}
28 <a href="?page={{ page_obj.next_page_number }}">Następne</a>
29 {% endif %}
30 </p>
31 {% endif %}
32
33 </body>
34</html>
Kolejne wiadomości odczytujemy i wyświetlamy w pętli przy użyciu tagu {% for %}.
Dostęp do właściwości obiektów umożliwia operator kropki, np.: {{ wiadomosc.autor.username }}.
Linki nawigacyjne tworzymy w instrukcji warunkowej {% if is_paginated %}.
Obiekt page_obj zawiera następujące właściwości:
has_previous– zwracaTrue, jeżeli jest poprzednia strona;previous_page_number– numer poprzedniej strony;next_page_number– numer następnej strony;number– numer aktualnej strony;paginator.num_pages– ilość wszystkich stron.
Numer strony do wyświetlenia przekazujemy w zmiennej page adresu URL.
7.2.8. Dodawanie wiadomości
Zadanie to zrealizujemy wykorzystując widok CreateView. Aby ułatwić dodawanie wiadomości
dostosujemy klasę widoku tak, aby użytkownik nie musiał wprowadzać pola autor.
Na początek dopiszemy w pliku czat/urls.py skojarzenie adresu URL dodaj/
z wywołaniem zaimportowanej z pliku views.py klasy DodajWiadomosc jako funkcji:
10 path('dodaj/', login_required(views.DodajWiadomosc.as_view()), name='dodaj'),
Dalej w pliku czat/views.py umieszczamy kod:
19class DodajWiadomosc(CreateView):
20 model = Wiadomosc
21 fields = ['tekst', 'data_pub']
22 context_object_name = 'wiadomosci'
23 success_url = '/lista'
24
25 def get_initial(self):
26 initial = super(DodajWiadomosc, self).get_initial()
27 initial['data_pub'] = timezone.now()
28 return initial
29
30 def form_valid(self, form):
31 wiadomosc = form.save(commit=False)
32 wiadomosc.autor = self.request.user
33 wiadomosc.save()
34 messages.success(self.request, "Dodano wiadomość!")
35 return super(DodajWiadomosc, self).form_valid(form)
36
Klasa DodajWiadomosc dziedziczy z klasy CreateView. Określamy jej właściwości i nadpisujemy wybrane metody:
fields– pozwala wskazać pola, które mają znaleźć się na formularzu;get_initial()– metoda pozwala ustawić domyślne wartości dla wybranych pól. Wykorzystujemy ją do zainicjowania poladata_pubaktualna datą:initial['data_pub'] = timezone.now().form_valid()– metoda, która sprawdza poprawność przesłanych danych i zapisuje je w bazie:wiadomosc = form.save(commit=False)– tworzymy obiekt wiadomości, ale go nie zapisujemy;wiadomosc.autor = self.request.user– uzupełniamy dane autora;wiadomosc.save()– zapisujemy obiekt;messages.success(self.request, "Dodano wiadomość!")– przygotowujemy komunikat, który wyświetlony zostanie po dodaniu wiadomości.
7.2.8.1. Szablon
Domyślny szablon dodawania danych dla klasy CreateView nazywa się <nazwa modelu>_form.html.
W nowym pliku wstawiamy poniższą treść i zapisujemy pod nazwą templates/czat/wiadomosc_form.html:
1<!-- templates/czat/wiadomosc_form.html -->
2<!DOCTYPE html>
3<html lang="pl">
4<head>
5 <meta charset="UTF-8">
6 <title>Dodawanie wiadomości</title>
7</head>
8<body>
9 <h1>Dodaj wiadomość</h1>
10 <form method="POST">
11 {% csrf_token %}
12 {{ form.as_p }}
13 <button type="submit">Zapisz</button>
14 </form>
15
16 <h2>Lista wiadomości:</h2>
17 <ol>
18 {% for wiadomosc in wiadomosci %}
19 <li>
20 <strong>{{ wiadomosc.autor.username }}</strong> ({{ wiadomosc.data_pub }}):
21 <br /> {{ wiadomosc.tekst }}
22 </li>
23 {% endfor %}
24 </ol>
25
26 <p><a href="{% url 'czat:wiadomosci' %}">Strona główna</a></p>
27
28 </body>
29</html>
W szablonie templates/czat/index.html wstawiamy jeszcze po nagłówku <h1> kod wyświetlający komunikaty:
{% if messages %}
<ul>
{% for komunikat in messages %}
<li>{{ komunikat|capfirst }}</li>
{% endfor %}
</ul>
{% endif %}
7.2.8.2. Ćwiczenie
Umieść link do dodawania wiadomości na końcu strony Lista wiadomości.
Dodaj jakąś wiadomość:
7.2.9. Edycja wiadomości
Widok pozwalający na edycję wiadomości i jej aktualizację dostępny będzie
pod adresem /edytuj/<pk>, gdzie <pk> będzie identyfikatorem
obiektu do zaktualizowania. Zaczniemy od uzupełnienia pliku urls.py:
11 path('edytuj/<pk>', login_required(views.EdytujWiadomosc.as_view()), name='edytuj'),
Nowością w powyższym kodzie jest definicja adresu z dodatkowym parametrem <pk> – nazwa jest tu skrótem
od ang. primary key, co znaczy „klucz główny”. Zmienna ta zawierać będzie identyfikator wiadomości
i dostępna będzie w klasie widoku, który obsłuży edycję wiadomości.
Do pliku views.py dopisujemy kod klasy EdytujWiadomosc, która dostosowuje wbudowany widok UpdateView:
38class EdytujWiadomosc(UpdateView):
39 model = Wiadomosc
40 from .forms import EdytujWiadomoscForm
41 form_class = EdytujWiadomoscForm
42 context_object_name = 'wiadomosci'
43 template_name = 'czat/wiadomosc_form.html'
44 success_url = '/lista'
45
46 def get_context_data(self, **kwargs):
47 context = super(EdytujWiadomosc, self).get_context_data(**kwargs)
48 context['wiadomosci'] = Wiadomosc.objects.filter(
49 autor=self.request.user)
50 return context
51
52 def get_object(self, queryset=None):
53 wiadomosc = Wiadomosc.objects.get(id=self.kwargs['pk'])
54 return wiadomosc
55
Nowe metody to:
get_object()– pobiera i zwraca wskazaną przez identyfikator w zmiennej pk wiadomość:wiadomosc = Wiadomosc.objects.get(id=self.kwargs['pk']).get_context_data()– pozwala przekazać do szablonu dodatkowe dane, w tym przypadku listę wiadomości, ale tylko zalogowanego użytkownika: (context['wiadomosci'] = Wiadomosc.objects.filter(autor=self.request.user)).
Pozostałe właściwości model, context_object_name, template_name i success_url
wyjaśniliśmy wcześniej. Jak widać, do edycji wiadomości wykorzystamy ten sam szablon,
którego użyliśmy podczas dodawania.
Formularz jednak dostosujemy. Wykorzystamy właściwość form_class,
której przypisujemy utworzoną w nowym pliku czat/forms.py klasę zmieniającą domyślne ustawienia:
1from django.forms import ModelForm, TextInput
2from .models import Wiadomosc
3
4
5class EdytujWiadomoscForm(ModelForm):
6 class Meta:
7 model = Wiadomosc
8 fields = ['tekst', 'data_pub']
9 exclude = ['autor']
10 widgets = {'tekst': TextInput(attrs={'size': 60})}
Klasa EdytujWiadomoscForm oparta jest na wbudowanej klasie ModelForm.
Właściwości formularza określamy w podklasie Meta:
model– oznacza to samo co w widokach, czyli model, dla którego tworzony jest formularz;fields– to samo co w widokach, lista pól do wyświetlenia;exclude– opcjonalnie lista pól do pominięcia;widgets– słownik, którego klucze oznaczają pola danych, a ich wartości odpowiadające im w formularzach HTML typy pól i ich właściwości, np. rozmiar.
Teraz w szablonie wiadomosc_list.html musimy dodać link, aby zalogowany użytkownik mógł
edytować swoje wiadomości. Kod wypisujący wiadomości w znaczniku <li> przyjmie następującą postać:
21 <li>
22 <strong>{{ wiadomosc.autor.username }}</strong> ({{ wiadomosc.data_pub }}):
23 <br> {{ wiadomosc.tekst }}
24 {% if wiadomosc.autor.username == user.username %}
25 • <a href="{% url 'czat:edytuj' wiadomosc.id %}">Edytuj</a>
26 {% endif %}
27 </li>
7.2.9.1. Ćwiczenie
Wejdź na stronę „Lista wiadomości” i kliknij link Edytuj:
Zmień treść wiadomości i kliknij przycisk Zapisz:
7.2.10. Usuwanie wiadomości
Do usuwania wiadomości wykorzystamy – podobnie jak w przypadku edycji – adres zawierający jej identyfikator:
/edytuj/<pk>. Uzupełniamy więc plik urls.py:
12 path('usun/<pk>', login_required(views.UsunWiadomosc.as_view()), name='usun'),
Na końcu pliku views.py umieszczamy kod klasy UsunWiadomosc, która wykorzystuje wbudowany widok DeleteView:
57class UsunWiadomosc(DeleteView):
58 model = Wiadomosc
59 template_name = 'czat/wiadomosc_usun.html'
60 success_url = '/lista'
Domyślny szablon dla tego widoku przyjmuje nazwę <nazwa-modelu>_confirm_delete.html,
dlatego uprościliśmy jego nazwę we właściwości template_name. Tworzymy więc plik wiadomosc_usun.html:
1<!-- templates/czat/wiadomosc_usun.html -->
2<!DOCTYPE html>
3<html lang="pl">
4<head>
5 <meta charset="UTF-8">
6 <title>Usuwanie wiadomości</title>
7</head>
8<body>
9 <h1>Usuń wiadomość</h1>
10 <form method="POST">
11 {% csrf_token %}
12 <p>Czy na pewno chcesz usunąć wiadomość:<br /><i>{{ object }}</i>?</p>
13 <button type="submit">Usuń</button>
14 </form>
15
16 <p><a href="{% url 'czat:lista' %}">Lista wiadomości</a></p>
17 </body>
18</html>
Tag {{ object }} zostanie zastąpiony treścią wiadomości zwróconą przez funkcję __str__() modelu.
7.2.10.1. Ćwiczenie
W szablonie
wiadomosc_list.htmlza linkiem Edytuj wstaw podobny link Usuń:• <a href="{% url 'czat:usun' wiadomosc.id %}">Usuń</a>, aby zalogowany użytkownik mógł usunąć wiadomość.Wejdź na stronę „Lista wiadomości” i kliknij link Usuń:
Potwierdź usunięcie wiadomości:
7.2.11. Materiały
Strona projektu Django https://www.djangoproject.com/
Co to jest framework? http://pl.wikipedia.org/wiki/Framework
Co nieco o HTTP i żądaniach GET i POST http://pl.wikipedia.org/wiki/Http
Materiały Python 101
udostępniane przez
Centrum Edukacji Obywatelskiej na licencji
Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowa.
- Utworzony:
2026-05-30 o 19:12 w Sphinx 7.3.7
- Autorzy: