Creare un applicazione blog con django, parte 5: scriviere viste django

Una vista Django è solo una funzione Python che riceve una richiesta Web e restituisce una risposta Web. Tutta la logica per restituire la risposta desiderata va all'interno della vista.

Innanzitutto, creamo le viste delle nostre applicazioni, poi definiamo un URL per ciascuna vista ed infine creeremo i templates HTML per renderizzare i dati generati dalle viste. Ogni vista renderizzerà un template passandole variabili e restituirà una risposta HTTP con l'output renderizzato.

Creare viste di lista e dettaglio

Iniziamo a creare una vista per visualizzare la lista dei post. Modifica il file blog/views.py della tua applicazione blog e farlo diventare così:

# blog/views.py

from django.shortcuts import render, get_object_or_404

from .models import Post

def post_list(request):
   posts = Post.published.all()
   return render(request,
                 'blog/post_list.html',
                 {'posts': posts})

La vista post_list prende l'oggetto request come unico argomento. Tenere presente che questo argomento è richiesto da tutte le viste. In questa vista, stiamo recuperando tutti i post con lo stato published utilizzando il manager published che abbiamo creato in precedenza.

La funzione render() prende l'oggetto request, il percorso di template e le variabili di contesto per renderizzare il template specificato. Esso restituisce un oggetto HttpResponse con il testo renderizzato (in genere, il codice HTML).

Creiamo una seconda vista per visualizzare un singolo post. Aggiungi la seguente funzione al file blog/views.py:

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})

Questa è la vista di dettaglio del post. Questa vista prende gli argomenti year, month, day e post per recuperare un post pubblicato con lo slug e la data date. Nota che quando abbiamo creato il modello Post, abbiamo aggiunto l'argomento unique_for_date al campo slug. In questo modo, ci assicuriamo che ci sia un solo post con uno slug per una determinata data e, quindi, possiamo recuperare singoli post utilizzando data e slug. Nella vista di dettaglio, utilizziamo la funzione get_object_or_404() per recuperare il post desiderato. Questa funzione recupera l'oggetto che corrisponde agli argomenti specificati o genera HTTP 404 (pagina non trovata) se l'oggetto non esiste. Infine, usiamo la funzione render() per renderizzare il post recuperato utilizzando un template.

Aggiungere URL alle tue viste

I modelli di URL ti consentono di mappare gli URL alle viste. Un modello di URL è composto da una stringa, una vista e facoltativamente un nome che consente di nominare l'URL a livello di progetto. Django esamina ogni modello di URL e si ferma al primo che corrisponde all'URL richiesto. Poi, Django importa la vista del modello di URL corrispondente e la esegue, passando un'istanza della classe HttpRequest e parole chiave.

Creare un file urls.py nella directory dell'applicazione blog e aggiungi il seguente codice:

# blog/urls.py

from django.urls import path

from . import views

app_name = 'blog'

urlpatterns = [
   # post views
   path('', views.post_list, name='post_list'),
   path('<int:year>/<int:month>/<int:day>/<slug:post>/',
        views.post_detail,
        name='post_detail'),
]

Nel codice precedente, abbiamo definito un namespace dell'applicazione con la variabile app_name. Questo ci consente di organizzare gli URL in base all'applicazione e di utilizzare il nome quando si riferisce ad essi. Abbiamo definito due diversi modelli utilizzando la funzione path(). Il primo modello di URL non prende alcun parametro ed è mappato alla vista post_list. Il secondo modello prende i seguenti quattro parametri ed è mappato alla vista post_detail:

  • year: richiede un numero intero
  • month: richiede un numero intero
  • day: richiede un numero intero
  • post: Può essere composto da parole e trattini

Utilizziamo parentesi angolari per acquisire i valori dall'URL. Qualsiasi valore specificato nel modello di URL come <parametro> viene acquisito come una stringa. Utilizziamo i convertitori di percorso, come <int: year>, per abbinare e restituire un numero intero e <slug: post> per abbinare uno slug (una stringa composta da lettere o numeri ASCII, più il trattino e caratteri di sottolineatura). Puoi vedere tutti i convertitori di percorso forniti da Django qui .

Ora, è necessario includere i modelli di URL dell'applicazione blog nei modelli di URL del progetto. Modifica il file mysite/urls.py e farlo diventare così:

# mysite/urls.py

from django.urls import path, include
from django.contrib import admin

urlpatterns = [

   path('blog/', include('blog.urls', namespace='blog')),
   path('admin/', admin.site.urls),

]

Il nuovo modello di URL definito con include si riferisce ai modelli di URL definiti nell'applicazione blog in modo che siano inclusi nel percorso blog/. Includiamo questi pattern nel namespace blog. I namespace devono essere univoci per l'intero progetto. Dopo faremo riferimento agli URL del nostro blog includendo il namespace in questo modo blog: post_list e blog: post_detail. Puoi trovare ulteriori informazioni su namespace di URL qui .

URL canonici per i modelli

Puoi utilizzare l'URL post_detail che hai definito nella sezione precedente per creare l'URL canonico per gli oggetti Post. La convenzione in Django è quella di aggiungere un metodo get_absolute_url() al modello che restituisce l'URL canonico dell'oggetto. Per questo, utilizziamo il metodo reverse() che ti consente di creare URL in base al loro nome e passando parametri opzionali. Modifica il file blog/models.py e aggiungi il seguente codice:

# blog/models.py

from django.urls import reverse

class Post(models.Model):
   # ...
   def get_absolute_url(self):

       args=[
           self.publish.year,
           self.publish.month,
           self.publish.day,
           self.slug,
           ]
       return reverse('blog:post_detail', args=args)

Utilizzeremo il metodo get_absolute_url() nei nostri template per creare un collegamento ai post specifici.

Fin qui, il file blog/models.py ora dovrebbe apparire così:

# blog/models.py

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse


class PublishedManager(models.Manager):
   def get_queryset(self):
       # Visualizza solo post pubblicati
       return super().get_queryset().filter(status='published')

class Post(models.Model):
   STATUS_CHOICES = (
       ('draft', 'Draft'),
       ('published', 'Published'),
   )
   title = models.CharField(max_length=250)
   slug = models.SlugField(max_length=250,
                           unique_for_date='publish')
   author = models.ForeignKey(User,
                              on_delete=models.CASCADE,
                              related_name='blog_posts')
   body = models.TextField()
   publish = models.DateTimeField(default=timezone.now)
   created = models.DateTimeField(auto_now_add=True)
   updated = models.DateTimeField(auto_now=True)
   status = models.CharField(max_length=10,
                             choices=STATUS_CHOICES,
                             default='draft')

   objects = models.Manager() # The default manager.
   published = PublishedManager() # The custom manager.

   class Meta:
       ordering = ('-publish',)

   def __str__(self):
       return self.title

   def get_absolute_url(self):
       args=[
           self.publish.year,
           self.publish.month,
           self.publish.day,
           self.slug,
           ]
       return reverse('blog:post_detail', args=args)

Per ora è tutto. Il prossimo tutorial è aggiungere template HTML per visualizzare i post.


Se ti piace il mio contenuto, supportami! grazie.

Post correlati