Video Corso Django 1.11 - Programmare in Python

Crea il Tuo Blog con Django 1.11 e Bootstrap 3.3.7

09: get_absolute_url

Fin'ora abbiamo ottenuto i link a ciascun post singolo tramite "hardcoding", ovvero specificandoli in maniera diretta, utilizzando la chiave primaria(chiamata anche id) e lo slug di ciascun post:

<!--DOCTYPE html -->
<html>
    <body>
        {% for object in object_list %}

         <a href="/{{object.id}}/{{object.slug}}/"><h1>{{object.titolo}}</h1></a>

        {% endfor %}
    </body>
</html>

Ma il tutto è poco elegante e sopratutto rende il programma meno modulare; Noi vogliamo che la nostra app possa essere utilizzata anche in altri progetti: cosa succederebbe se il pattern url associato variasse anche solo di poco? Ad esempio:

#urls.py

urlpatterns = [
    (...)

    url(r'^asd/(?P<id>\d+)/(?P<slug>[\w-]+)/$', DetailView.as_view(
        model = Post,
        template_name = "post_singolo.html"), name="singolo")

    (...)
]

Otterremo sicuramente un errore.

Per ovviare a questo problema torniamo ora nel nostro models.py e creiamo una funzione che sia in grado di restituirci l'url del nostro post, qualunque esso sia! Per convenzione, chiameremo questa funzione "get_absolute_url", e sarà basata a sua volta su una funzione presente in django.core.urlresolvers, la funzione reverse.

from django.db import models
from django.core.urlresolvers import reverse
# Create your models here.

class Post(models.Model):
    titolo = models.CharField(max_length=120)
    contenuto = models.TextField()
    data = models.DateTimeField(auto_now=False, auto_now_add=True) # auto_now_add setta quando il file viene creato, quindi solo una volta
    slug = models.SlugField()

    # python 3
    def __str__(self):
        return self.titolo

    def get_absolute_url(self):
        return reverse("singolo", kwargs={"id": self.id, "slug": self.slug})

A questo punto tornando nel template "lista_post.html", possiamo modificare i link in maniera appropriata, richiamando su ciascun oggetto del ciclo for la corrispondente funzione get_absolute_url:

 <!--DOCTYPE html -->
<html>
    <body>
        {% for object in object_list %}

         <a href="{{object.get_absolute_url}}"><h1>{{object.titolo}}</h1></a>

        {% endfor %}
    </body>
</html>
Menu della Serie