Python Django: modificare le URL
Nel post precedente abbiamo visto l’area di amministrazione, e come concludevo, quella non è utilizzabile se non per questioni di emergenza o di modifica sui dati del Database.
Quindi dovremo cominciare a mettere mano alle interfacce lato pubblico, ma prima dobbiamo ragionare un attimo sulle funzionalità di queste ultime.
Nel caso di un blog è necessario avere più schermate. Una certamente è quella di “dettaglio” ovvero dove leggiamo il Post completo di tutti i suoi elementi. Una seconda è la lista di Post dove poter effettuare la scelta prima di entrare nel dettaglio.
Se ipotizziamo di avere centinaia di Post, il solo SLUG visto in precedenza non è sufficiente poiché potremo creare due Post con il medesimo titolo. Se sul Database non è un problema visto l’ID univoco del dato, discorso differente per le URL. In questo caso Python potrebbe restituire un errore poiché si aspetta un risultato solo ed invece ne arrivano due. Una tecnica potrebbe essere quella di usare le date.
Anteponendo /anno/mese/giorno/ è ragionevole che questo problema non si verifichi. Ok ma questa è una cosa dinamica, cioè la URL deve essere composta dal programma e non dobbiamo preoccuparci di questa cosa.
Post in stato pubblicato
Sicuramente avremo bisogno di mostrare i link dei post che sono solo nello stato Pubblicato, ci vari modi per tirare fuori, quella più riutilizzabile e scrivere una piccola classe in “models.py”. Tra i modelli andremo ad usare “Manager” che ci permette di fare una Query agnostica sul database. Aggiungiamo prima di Class Post questa nuova classe:
class PublishedManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(status='published')
La sfruttiamo subito andando ad aggiungere una variabile, che inseriremo prima di “Class Meta”
published = PublishedManager()
Lista e dettaglio dei post
Andiamo quindi a definire una oggetto che richiamerà la lista dei Post e il suo dettaglio. Per fare questo interveniamo sul file “views.py” dentro la cartella Blog.
view.py
from django.shortcuts import render, get_object_or_404
from .models import Post
# Create your views here.
def post_list(request):
posts = Post.published.all()
return render(request, 'blog/post/list.html', {'posts': posts})
def post_detail(request, year, month, day, post):
post = get_object_or_404(Post,
slug=post,
status='published',
publish__year=year,
publish__month=month,
publish__day=day)
return render(request,'blog/post/detail.html',{'post': post})
Abbiamo caricato Post dal model che avevamo creato nel capitolo 02, quindi siamo andati a creare due funzioni, “post_list” e “post_detail”.
Nella prima funzione, andiamo a pescare tutti i Post che sono nello stato Published e andiamo a “stampare” i dati dentro un file HTML che vedremo nella prossima puntata. All’interno andiamo anche ad indicare delle variabili che ci serviranno come filtro in futuro.
Con la seconda funzione, più complessa perché deve prendere maggiori dettagli, andiamo a pescare uno specifico Post che sono nello stato Published, di questi prendiamo lo SLUG e i dati temporali per “stamparli” dentro un file HTML, esattamente come nella funzione precedente.
Menzione particolare alla scorciatoia get_object_or_404, che in caso di fallimento tornerà la pagina 404 anziché dare errore.
Comporre la URL
A questo punto, come anticipato, dobbiamo creare una URL unica che sarà composta da /anno/mese/giorno/slug
Per fare questo creiamo un nuovo file che si chiamerà “urls.py”
urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.post_list, name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
]
In questo file, siamo andati a caricare il file views, che abbiamo modificato per primo. Abbiamo creato una lista “urlpatterns” dove al suo interno è codificata la URL completa che ci servirà per cliccare sul link e portarci in modo corretto ai dati richiesti sul file HTML che abbiamo definito in precedenza. Altri esempi li troviamo nella Documentazione di Django. Sarà sicuramente più chiaro nel momento in cui andremo a lavorare proprio con i template HTML.
Ora non resta che informare Django di questa modifica poiché lo schema delle URL, compreso /admin che abbiamo utilizzando nel capitolo scorso, sono memorizzate nel file “urls.py” nella cartella “miosito”.
urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls', namespace='blog')),
]
Come si può intuire qui possiamo creare le URL che serviranno al nostro progetto, o alle nostre App. Ci sarà modo di ritornarci sopra.
Terminiamo con la creazione di una funzione che ci estrae la URL, poiché quanto fatto fino ad ora costruisce tutto l’impianto, ma se dobbiamo andare a stampare un link abbiamo necessità di una funzione apposita. La costruiamo nel file “models.py”. In cima tra le “import” andiamo ad aggiungere:
from django.urls import reverse
Mentre in fondo al file aggiungiamo questa funzione, attenzione all’indentatura, poiché questa funzione è all’interno della “Class Post”
def get_absolute_uri(self):
return reverse('blog:post_detail',args=[
self.publish.year,
self.publish.month,
self.publish.day,
self.slug
])
Concludiamo questo capitolo, il prossimo andremo a mettere mano sui Template HTML e cominciare a costruire qualcosa di visivo.
Posted from my blog: https://blog.tosolini.info/
!discovery 30
!hiqvote
!BEER
!LUV
This post was shared and voted inside the discord by the curators team of discovery-it
Join our Community and follow our Curation Trail
Discovery-it is also a Witness, vote for us here
Delegate to us for passive income. Check our 80% fee-back Program