Porozmawiamy dziś o zmianach jakie zostały wprowadzone w Django 2.0 w kwestii tworzenia URL. Warto zaznaczyć, że dopiero wersja 2.0 wprowadza cywilizowany sposób tworzenia tych linków w mojej opinii.

Podstawy

Jeśli miałeś / miałaś styczność z PHP to zapewne wiesz, że generowanie linków jest tam banalnie proste. Wystarczy stworzyć np. index.php i cała infrastruktura serwera zrobi wszystko za nas, czyli “przetworzy” plik na adres. Nam pozostanie tylko wpisać localhost/index.php i voila.

W Python i samym Django nie ma tak łatwo. Analogiczna sytuacja jak z PHP wywali błąd serwera. Jest to spowodowane tym, że serwery dla Python interpretują klasy aplikacji, a nie pliki. Na pierwszy rzut oka może się to wydawać bardziej skomplikowane, i takie jest, ale w końcu wszystkiego da się nauczyć.

Aby zaprojektować adresy URL dla aplikacji, należy utworzyć moduł Pythona, zwany nieformalnie URLconf (konfiguracja adresu URL). Moduł ten jest czystym kodem Pythona i odwzorowuje wyrażenia ścieżki adresu URL na funkcje Pythona (twoje widoki). Oczywiście nic nie stoi na przeszkodzie by to zmienić. Odpowiada za to ROOT_URLCONF w pliku settings.py.

Django ładuje ten moduł Pythona i wyszukuje zmienną urlpatterns. Powinna to być lista instancji django.urls.path i / lub django.urls.re_path.

Jak wygląda tworzenie URL w Django 2.0

Tutaj mamy nowość, ponieważ z Django 2.0 wyleciała instancja django.conf.urls.url, która odpowiadała za tworzenie urli w naszym projekcie. Autorzy zdali sobie chyba sprawę z tego, że stary format linków nie był najczytelniejszy na świecie i postanowili to naprawić nowością w postaci django.urls.path.

Przykład:

from django.urls import path

from . import views

urlpatterns = [
   path('articles/2003/', views.special_case_2003),
   path('articles/<int:year>/', views.year_archive),
   path('articles/<int:year>/<int:month>/', views.month_archive),
   path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail, name=’detail’),
]

Łatwo odgadnąć co znaczy int:year, int:month – to po prostu data. Natomiast slug:slug to przekazany do linku za pomocą metody get_absolute_url kawałek url np. locahost:8000/ala-ma-kota/. Tym slug’iem będzie tutaj ala-ma-kota/. Wykorzystuję się do do tworzenia tzw. seo-friendly url. Warto zapamiętać.

Możemy się również natknąć na coś takiego <int:pk>. Jest to nic innego jak przekazany do URL id (identyfikator) naszego wiersza z bazy danych modelu (np. pierwszy zarejestrowany klient, albo pierwszy wpis z bloga). Tutaj nie trzeba dopisywać żadnej metody, Django sam sobie to potrafi pobrać i przekazać do URL.

Dla formalności przykładowa metoda get_absolute_url. Piszemy ją w klasie modelu.

slug = models.SlugField(unique=True)

def get_aboslute_url(self):

    form django.urls import reverse

    return reverse(‘detail’, kwargs={‘slug’: self.slug})

Jak widać, nic trudnego. ‘detail’ to nasz atrybut name w metodzie, po tym Django wie, do którego url jest przekazywany slug. Kwargs to słownik. W słowniku zapisujemy dane na zasadzie klucz:wartość. W tym przypadku kluczem jest ‘slug’ i przypisujemy do niego zmienną modelu slug, który ma zapisany kawałek linku. Klucz jest przekazywany do naszego path.

Jak wygląda tworzenie URL w Django 2.0 według starej konwencji

Jak komuś podoba się stary styl linków to nic nie stoi na przeszkodzie by z tego nie skorzystać w wersji 2.0. W pliku urls.py zamiast ładować instancje django.urls.path musimy załadować django.urls.re_path.

Przykład:

from django.urls import include, re_path

urlpatterns = [
   re_path(r'^index/$', views.index, name='index'),
   re_path(r'^bio/(?P<username>\w+)/$', views.bio, name='bio'),
   re_path(r'^weblog/', include('blog.urls')),
   ...
]

Co znaczą poszczególne symbole:

  • r – regex, wyrażenie regularne
  • ^ – oznacza początek tekstu
  • $ – oznacza koniec tekstu
  • \d – oznacza cyfrę (digit / digits)
  • \w – oznacza słowo (word)
  • ?P<nasz parametr> – oznacza parametr

Przekazywanie parametrów do url odbywa się na takiej samej zasadzie jak akapit wyżej, jedynie co jest różne to sposób formatowania. A które formatowanie url się przyjemniej czyta? Na to pytanie trzeba odpowiedzieć sobie indywidualnie.

Jak wygląda tworzenie URL w Django poniżej wersji 2.0

Przejdźmy od razu do przykładu, bo jak porównasz to sobie z powyższą wersja zobaczysz aż dwie różnice:

from django.conf.urls import include, url

urlpatterns = [
   url(r'^index/$', views.index, name='index'),
   url(r'^bio/(?P<username>\w+)/$', views.bio, name='bio'),
   url(r'^weblog/', include('blog.urls')),
   ...
]

Pierwsza różnica: zamiast from django.urls import re_path importujemy from django.conf.urls import url. Druga różnica: definiowanie pojedyńczego url odbywa się za pomocą url a nie re_path. Nic więcej, reszta zasad jest taka sama jak powyżej.

Aha, sugerujemy byś przyzwyczaił się do tej wersji właśnie, więcej softu zostało napisane w Django poniżej 2.0. Niestety 🙂