diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:17 -0500 |
commit | da78a9e329e272dedb2400b79a3bdeebff387d47 (patch) | |
tree | e6ef8aa7c43556f55ddfe031a01cf0a8fa271bfe /files/it/learn/server-side | |
parent | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (diff) | |
download | translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.tar.gz translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.tar.bz2 translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.zip |
initial commit
Diffstat (limited to 'files/it/learn/server-side')
14 files changed, 4823 insertions, 0 deletions
diff --git a/files/it/learn/server-side/django/admin_site/index.html b/files/it/learn/server-side/django/admin_site/index.html new file mode 100644 index 0000000000..6cb1fac11a --- /dev/null +++ b/files/it/learn/server-side/django/admin_site/index.html @@ -0,0 +1,361 @@ +--- +title: 'Django Tutorial Part 4: Django admin site' +slug: Learn/Server-side/Django/Admin_site +tags: + - Articolo + - Codice + - Python + - Script + - Server + - Tutorial + - django + - django_admin + - imparare + - inizio + - nuovo +translation_of: Learn/Server-side/Django/Admin_site +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}</div> + +<p class="summary">Dopo aver creato i modelli per la nostra <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>, useremo il sito di Django Admin per aggiungere alcuni dati "reali" sui libri. Per prima cosa ti mostreremo come registrare i modelli con il sito di amministrazione, quindi ti mostreremo come accedere e creare alcuni dati. Alla fine dell'articolo mostreremo alcuni modi per migliorare ulteriormente la presentazione del sito di amministrazione.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td>Prima completa: <a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a>.</td> + </tr> + <tr> + <th scope="row">Obbiettivi:</th> + <td>Per capire i vantaggi e le limitazioni del sito di amministrazione Django, e usarlo per creare alcuni record per i nostri modelli.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica">Panoramica</h2> + +<p>L'applicazione di amministrazione Django può utilizzare i modelli per creare automaticamente un'area del sito che è possibile utilizzare per creare, visualizzare, aggiornare ed eliminare record. Questo può farti risparmiare molto tempo durante lo sviluppo, rendendo molto facile testare i tuoi modelli e capire se hai i dati giusti. L'applicazione di amministrazione può anche essere utile per la gestione dei dati in produzione, a seconda del tipo di sito Web. Il progetto Django lo consiglia solo per la gestione interna dei dati (vale a dire solo per gli amministratori o le persone interne alla tua organizzazione), poiché l'approccio model-centric non è necessariamente la migliore interfaccia possibile per tutti gli utenti e espone molti dettagli inutili sui modelli.</p> + +<p>Tutta la configurazione richiesta per includere l'applicazione di amministrazione nel tuo sito Web è stata eseguita automaticamente quando hai creato il progetto skeleton (per informazioni sulle reali dipendenze necessarie, consulta <a href="https://docs.djangoproject.com/en/2.1/ref/contrib/admin/">Django docs</a>). Di conseguenza, tutto ciò che devi fare per aggiungere i tuoi modelli all'applicazione admin è registrarli. Alla fine di questo articolo forniremo una breve dimostrazione di come è possibile configurare ulteriormente l'area di amministrazione per visualizzare meglio i dati del modello.</p> + +<p>Dopo aver registrato i modelli, mostreremo come creare un nuovo "superutente", accedere al sito e creare alcuni libri, autori, istanze di libri e generi. Questi saranno utili per testare le viste e i modelli che inizieremo a creare nel prossimo tutorial.</p> + +<h2 id="Registrare_i_models">Registrare i models </h2> + +<p>Apri <strong>admin.py</strong> in catalog (<strong>/locallibrary/catalog/admin.py</strong>). Notare che essa già contiene l'istruzione <code>django.contrib.admin</code>:</p> + +<pre class="brush: python">from django.contrib import admin + +# Register your models here. +</pre> + +<p>Registrare i modelli copiando il seguente testo nella parte inferiore del file. Questo codice importa semplicemente i modelli e quindi le chiamate <code>admin.site.register</code> Per registrarli.</p> + +<pre class="brush: python">from catalog.models import Author, Genre, Book, BookInstance + +admin.site.register(Book) +admin.site.register(Author) +admin.site.register(Genre) +admin.site.register(BookInstance) +</pre> + +<div class="note"><strong>Note</strong>: Se hai accettato la sfida di creare un modello per rappresentare il linguaggio naturale di un libro, importalo e registralo anche tu (<a href="/en-US/docs/Learn/Server-side/Django/Models">see the models tutorial article</a>)!</div> + +<p>Questo è il modo più semplice di registrare un modello o modelli con il sito. Il sito di amministrazione è altamente personalizzabile e parleremo di altri modi per registrare i tuoi modelli più in basso.</p> + +<h2 id="Creare_un_superuser">Creare un superuser</h2> + +<p>Per accedere al sito admin, abbiamo bisogno di un account utente con lo stato del personale abilitato. Per poter visualizzare e creare record, abbiamo anche bisogno che questo utente abbia i permessi per gestire tutti i nostri oggetti. Puoi creare un account "superutente" che abbia accesso completo al sito e tutte le autorizzazioni necessarie usando manage.py. Chiamare il seguente comando, nella stessa directory di manage.py, per creare il superutente. Ti verrà richiesto di inserire un nome utente, un indirizzo email e una password complessa.</p> + +<pre class="brush: bash">python3 manage.py createsuperuser +</pre> + +<p>Una volta che questo comando è stato completato, un nuovo superutente sarà stato aggiunto al database. Ora riavvia il server di sviluppo in modo da poter verificare l'accesso:</p> + +<pre class="brush: bash">python3 manage.py runserver + +</pre> + +<h2 id="Loggarsi_come_superuser_e_usare_il_sito">Loggarsi come superuser e usare il sito</h2> + +<p>Per effettuare il login, utilizzare nell'URL <em>/admin</em> (esempio: <a href="http://127.0.0.1:8000/admin/">http://127.0.0.1:8000/admin</a>) e inserisci le tue nuove credenziali utente e password per superutente (verrai reindirizzato alla pagina di accesso e poi tornerai all'URL di / admin dopo aver inserito i tuoi dettagli). Questa parte del sito mostra tutti i nostri modelli, raggruppati per applicazione installata. È possibile fare clic sul nome di un modello per andare a una schermata in cui sono elencati tutti i record associati e è possibile fare ulteriori clic su tali record per modificarli. Puoi anche fare clic direttamente sul collegamento <strong>add </strong>accanto a ciascun modello per iniziare a creare un record di quel tipo.</p> + +<p><img alt="Admin Site - Home page" src="https://mdn.mozillademos.org/files/13975/admin_home.png" style="display: block; height: 634px; margin: 0px auto; width: 998px;"></p> + +<p>Clicca sul link <strong>Add </strong>a destra di <em>Books</em> per creare un nuovo libro (verrà mostrata una finestra di dialogo come sotto). Nota come il titolo di ogni campo, il tipo di widget utilizzato, e l' <code>help_text</code> (se presente) matcha il valore che hai specificato nel modello. </p> + +<p>Immettere i valori per i campi. Puoi creare nuovi autori o generi premendo il pulsante + vicino ai rispettivi campi (o seleziona i valori esistenti dagli elenchi se li hai già creati). Quando hai finito puoi premere <strong>SAVE</strong>, <strong>Save and add another</strong>, o <strong>Save and continue editing</strong> per salvare il record.</p> + +<p><img alt="Admin Site - Book Add" src="https://mdn.mozillademos.org/files/13979/admin_book_add.png" style="border-style: solid; border-width: 1px; display: block; height: 780px; margin: 0px auto; width: 841px;"></p> + +<div class="note"> +<p><strong>Note</strong>: A questo punto vorremmo che passassi un po 'di tempo ad aggiungere alcuni libri, autori e generi (ad es. Fantasy) alla tua applicazione. Assicurati che ogni autore e genere includa un paio di libri diversi (questo renderà le tue visualizzazioni di lista e di dettaglio più interessanti quando le implementeremo più avanti nella serie di articoli).</p> +</div> + +<p>Al termine dell'aggiunta di libri, fai clic sul link <strong>Home </strong>nel segnalibro in alto per tornare alla pagina principale dell'amministratore. Quindi fare clic sul link <strong>Libri </strong>per visualizzare l'elenco corrente di libri (o su uno degli altri collegamenti per vedere altri elenchi di modelli). Ora che hai aggiunto alcuni libri, l'elenco potrebbe essere simile allo screenshot qui sotto. Viene visualizzato il titolo di ogni libro; questo è il valore restituito nel metodo <strong>__str __ ()</strong> del modello Book che abbiamo specificato nell'ultimo articolo.</p> + +<p><img alt="Admin Site - List of book objects" src="https://mdn.mozillademos.org/files/13935/admin_book_list.png" style="border-style: solid; border-width: 1px; display: block; height: 407px; margin: 0px auto; width: 1000px;"></p> + +<p>Da questa lista puoi cancellare libri selezionando la checkbox vicino al libro che non vuoi, e selezionando l'azione <em>delete</em> dalla lista di azioni <em>Action</em>, e premendo il pulsante <strong>Go</strong>. Puoi anche aggiungere nuovi libri, premendo <strong>ADD BOOK</strong>. </p> + +<p>Puoi editare un libro selezionando il suo nome dal link. La pagina di edit, mostrata sotto, è uguale a quella di aggiunta di un nuovo libro. Le differenze principali sono il titolo (<em>Change book</em>) e l'aggiunta di <strong>Delete</strong>, <strong>HISTORY</strong> e <strong>VIEW ON SITE </strong>(questo ultimo bottone appare perchè abbiamo definito il metodo <code>get_absolute_url()</code> nel modello).</p> + +<p><img alt="Admin Site - Book Edit" src="https://mdn.mozillademos.org/files/13977/admin_book_modify.png" style="border-style: solid; border-width: 1px; display: block; height: 780px; margin: 0px auto; width: 841px;"></p> + +<p>Ora torna alla Home page (utilizzando il collegamento Home il percorso breadcrumb) e quindi visualizza gli elenchi Autore e Genere: dovresti averne già abbastanza creati da quando hai aggiunto i nuovi libri, ma sentiti libero di aggiungerne altri.</p> + +<p>Ciò che sicuramente non avrai, sono delle <em>Book Instances</em>, perchè non vengono create da Books (invece possiamo creare un <code>Book</code> da una <code>BookInstance</code> — questo è il funzionamento del campo di tipo <code>ForeignKey</code>). Naviga indietro alla Home page e premi il bottone Add associato. Notare il campo id, largo ed univoco, che viene utilizzato per identificare una singola copia di un libro in una libreria.</p> + +<p><img alt="Admin Site - BookInstance Add" src="https://mdn.mozillademos.org/files/13981/admin_bookinstance_add.png" style="border-style: solid; border-width: 1px; display: block; height: 514px; margin: 0px auto; width: 863px;"></p> + +<p>Crea un numero di questi record per ciascuno dei tuoi libri. Imposta lo stato come Disponibile per almeno alcuni record e In prestito per gli altri. Se lo stato non è Disponibile, imposta anche una data di scadenza futura.</p> + +<p>Questo è tutto! Ora hai imparato come configurare e utilizzare il sito di amministrazione. Hai anche creato record per Book, BookInstance, Genre e Author che saremo in grado di utilizzare una volta create le views e i modelli.</p> + +<h2 id="Configurazione_avanzata">Configurazione avanzata</h2> + +<p>Django fa un buon lavoro nel creare un sito admin di base usando le informazioni dei modelli registrati:</p> + +<ul> + <li>Ogni modello ha un elenco di record individuali, identificati dalla stringa creata con il metodo __str __ () del modello e collegati a viste / moduli di dettaglio per la modifica. Per impostazione predefinita, questa vista ha un menu azioni in alto che è possibile utilizzare per eseguire operazioni di eliminazione di massa sui record.</li> + <li>I form di registrazione dei dettagli del modello per la modifica e l'aggiunta di record contengono tutti i campi nel modello, disposti verticalmente nell'ordine di dichiarazione.</li> +</ul> + +<p>Puoi rendere ancora più semplice da utilizzare l'interfaccia, ecco alcune delle cose che puoi fare:</p> + +<ul> + <li>Visualizzazioni elenco: + <ul> + <li>Aggiungi campi / informazioni aggiuntivi visualizzati per ogni record.</li> + <li>Aggiungi filtri per selezionare i record elencati, in base alla data o ad un altro valore di selezione (ad es. Stato del prestito del libro).</li> + <li>Aggiungi opzioni aggiuntive al menu azioni nelle visualizzazioni elenco e scegli dove questo menu viene visualizzato nel modulo.</li> + </ul> + </li> + <li>Viste dettagliate + <ul> + <li>Scegli quali campi mostrare (o nascondere), oltre al loro raggruppamento, ordine, se sono editabili, widget usati, orientazione, ecc.</li> + <li>Aggiungi campi correlati a un record per consentire la modifica in linea (ad esempio aggiungi la possibilità di aggiungere e modificare i record del libro mentre crei il record dell'autore).</li> + </ul> + </li> +</ul> + +<p>In questa sezione esamineremo alcune modifiche che miglioreranno l'interfaccia per la nostra libreria locale, tra cui l'aggiunta di ulteriori informazioni agli elenchi di modelli di libri e autori e il miglioramento del layout delle loro viste di modifica. Non cambieremo la presentazione del modello Lingua e genere perché hanno solo un campo ciascuno, quindi non c'è alcun vantaggio reale nel farlo!</p> + +<p>Per maggiori informazioni sulle customizzazioni possibili, consultare <a href="https://docs.djangoproject.com/en/2.1/ref/contrib/admin/">The Django Admin site</a> (Django Docs).</p> + +<h3 id="Registrare_una_classe_ModelAdmin">Registrare una classe ModelAdmin</h3> + +<p>Per cambiare la visualizzazione dei modelli nell'interfaccia admin, dovremo definire una classe <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#modeladmin-objects">ModelAdmin</a> e registrarla col modello.</p> + +<p>Cominciamo col modello di <code>Author</code>. Apri <strong>admin.py</strong> nella applicazione catalog (<strong>/locallibrary/catalog/admin.py</strong>). Commentiamo la registrazione originaria (scrivendo prima della riga di codice un carattere) del modello <code>Author</code>:</p> + +<pre class="brush: js"># admin.site.register(Author)</pre> + +<p>Aggiungi una nuova registrazione <code>AuthorAdmin</code>.</p> + +<pre class="brush: python"># Define the admin class +class AuthorAdmin(admin.ModelAdmin): + pass + +# Register the admin class with the associated model +admin.site.register(Author, AuthorAdmin) +</pre> + +<p>Aggiungiamo anche le classi <code>ModelAdmin</code> per <code>Book</code>, e <code>BookInstance</code>. Commentiamo anche qui le vecchie registrazioni:</p> + +<pre class="brush: js"># admin.site.register(Book) +# admin.site.register(BookInstance)</pre> + +<p>Per registrare i nuovi modelli, per i propositi di questa dimostrazione, useremo il decoratore <code>@register</code> (che esegue la stessa azione della sintassi <code>admin.site.register()</code>):</p> + +<pre class="brush: python"># Register the Admin classes for Book using the decorator +@admin.register(Book) +class BookAdmin(admin.ModelAdmin): + pass + +# Register the Admin classes for BookInstance using the decorator +@admin.register(BookInstance) +class BookInstanceAdmin(admin.ModelAdmin): + pass +</pre> + +<p>Attualmente tutte le nostre classi di amministrazione sono vuote (vedi <code>pass</code>) cosi il comportamento di admin non e' cambiato! Ora possiamo estendere queste classi per definire i nostri specifici modelli di comportamento di admin.</p> + +<h3 id="Configurare_le_liste_di_visualizzazione">Configurare le liste di visualizzazione</h3> + +<p>La <em>LocalLibrary</em> attualmente mostra una lista degli autori usando il nome oggetto generato da <code>__str__()</code>. Questo va bene quando hai solo pochi autori, ma una volta che ne hai molti potresti finire per avere dei duplicati. Per differenziarli, o solo perché vuoi mostrare informazioni più interessanti su ciascun autore, puoi utilizzare ad esempio <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display">list_display</a> per aggiungere ulteriori campi alla visualizzazione. </p> + +<p>Sostituisci il tuo codice della classe <code>AuthorAdmin</code> con quello sotto. I campi da mostrare nella lista sono dichiaratiin una <em>tupla </em>nell'ordine desiderato, come mostrato sotto.</p> + +<pre class="brush: python">class AuthorAdmin(admin.ModelAdmin): + list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death') +</pre> + +<p>Naviga ora alla lista degli autori. I campi inseriti nella tupla ora dovrebbero essere mostrati:</p> + +<p><img alt="Admin Site - Improved Author List" src="https://mdn.mozillademos.org/files/14023/admin_improved_author_list.png" style="border-style: solid; border-width: 1px; display: block; height: 302px; margin: 0px auto; width: 941px;"></p> + +<p>Per il nostro modello <code>Book</code> mostreremo anche l'autore, <code>author</code> ed il genere, <code>genre</code>. <code>author</code> è un campo di tipo <code>ForeignKey</code> (uno-a-molti), quindi verrà rappresentato dal valore <code>__str__()</code> per il record associato. Rimpiazza la classe <code>BookAdmin</code> con la versione seguente.</p> + +<pre class="brush: python">class BookAdmin(admin.ModelAdmin): + list_display = ('title', 'author', 'display_genre') +</pre> + +<p>Sfortunatamente non possiamo specificare direttamente il campo <font face="Consolas, Liberation Mono, Courier, monospace">genre </font>in <code>list_display</code> perchè è un campo di tipo <code>ManyToManyField</code> (Django impedisce questa operazione perché ci sarebbe traffico di "accesso" molto costosa al database nel farlo). Invece definiremo una funzione <code>display_genre</code> per prendere le informazioni sotto forma di stringa (la funzione che abbiamo chiamato sopra, la definiremo di seguito).</p> + +<div class="note"> +<p><strong>Note</strong>: Mostrare il <code>genre</code> potrebbe non essere una buona idea qui, a causa del "costo" dell'operazione del database. Ti stiamo mostrando come, perché chiamare le funzioni nei tuoi modelli può essere molto utile per altri motivi, ad esempio per aggiungere un link Elimina accanto a ogni elemento nell'elenco</p> +</div> + +<p>Aggiungi il seguente codice nel tuo modello <code>Book</code> (<strong>models.py</strong>). Questa funzione crea una stringa contenente i primi tre valori del campo <code>genre</code> (se esistono) e creano una <code>short_description</code> che può essere utilizzata nel sito admin per questo metodo.</p> + +<pre class="brush: python"> def display_genre(self): + """Create a string for the Genre. This is required to display genre in Admin.""" + return ', '.join(genre.name for genre in self.genre.all()[:3]) + + display_genre.short_description = 'Genre' +</pre> + +<p>Dopo aver salvato il modello e aver aggiornato admin, apri il sito e vai alla lista di visualizzazione <em>Books</em>; ecco ciò che dovresti vedere:</p> + +<p><img alt="Admin Site - Improved Book List" src="https://mdn.mozillademos.org/files/14025/admin_improved_book_list.png" style="border-style: solid; border-width: 1px; display: block; height: 337px; margin: 0px auto; width: 947px;"></p> + +<p>Il modello <code>Genre</code> (ed il modello <code>Language</code>, se ne hai definito uno) entrambi hanno un singolo campo, quindi non ha senso creare un modello aggiuntivo per mostrare campi aggiuntivi.</p> + +<div class="note"> +<p><strong>Note</strong>: potrebbe essere utile aggiornare il modello della lista di <code>BookInstance</code> per mostrare almeno anche lo status e la data di restituzione. L'abbiamo inserita come sfida alla fine di questo capitolo!</p> +</div> + +<h3 id="Aggiungere_dei_filtri_alle_liste">Aggiungere dei filtri alle liste</h3> + +<p>Una volta che hai un sacco di elementi in una lista, può essere utile poter filtrare quali oggetti sono visualizzati. Questo viene fatto elencando i campi nell'attributo <code>list_filter</code>. Rimpiazza la classe corrente <code style="font-style: normal; font-weight: normal;">BookInstanceAdmin</code> con il codice di seguito.</p> + +<pre class="brush: python">class BookInstanceAdmin(admin.ModelAdmin): +<strong> list_filter = ('status', 'due_back')</strong> +</pre> + +<p>La visualizzazione elenco includerà ora una casella filtro sulla destra. Nota come puoi scegliere le date e lo stato per filtrare i valori:</p> + +<p><img alt="Admin Site - BookInstance List Filters" src="https://mdn.mozillademos.org/files/14037/admin_improved_bookinstance_list_filters.png" style="height: 528px; width: 960px;"></p> + +<h3 id="Organizzare_il_layout_della_visualizzazione_dettaglio">Organizzare il layout della visualizzazione dettaglio</h3> + +<p>Per impostazione predefinita, le viste di dettaglio dispongono tutti i campi verticalmente, nel loro ordine di dichiarazione nel modello. È possibile modificare l'ordine di dichiarazione, quali campi vengono visualizzati (o esclusi), se le sezioni vengono utilizzate per organizzare le informazioni, se i campi sono visualizzati orizzontalmente o verticalmente e anche quali widget di modifica vengono utilizzati nei moduli di amministrazione.</p> + +<div class="note"> +<p><strong>Note</strong>: I modelli <em>LocalLibrary</em> sono relativamente semplici, quindi non abbiamo un grosso bisogno di cambiare il layout; ne faremo comunque alcuni, solo a scopo dimostrativo.</p> +</div> + +<h4 id="Controllare_quali_campi_sono_visualizzati_e_come_sono_disposti">Controllare quali campi sono visualizzati e come sono disposti</h4> + +<p>Aggiorna la tua classe <code>AuthorAdmin</code> class e aggiungi la riga di codice <code>fields</code> mostrata sotto in grassetto:</p> + +<pre class="brush: python">class AuthorAdmin(admin.ModelAdmin): + list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death') +<strong> fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')]</strong> +</pre> + +<p>L'attributo fields elenca solo i campi che devono essere visualizzati nel modulo, in ordine. I campi vengono visualizzati verticalmente per impostazione predefinita, ma verranno visualizzati orizzontalmente se vengono ulteriormente raggruppati in una tupla (come mostrato nei campi "data" sopra).</p> + +<p>Nel tuo sito web vai alla vista dettagli dell'autore - ora dovrebbe apparire come mostrato di seguito:</p> + +<p><img alt="Admin Site - Improved Author Detail" src="https://mdn.mozillademos.org/files/14027/admin_improved_author_detail.png" style="border-style: solid; border-width: 1px; display: block; height: 282px; margin: 0px auto; width: 928px;"></p> + +<div class="note"> +<p><strong>Note</strong>: Puoi anche utilizzare l'attributo <code>exclude</code> per dichiarare una lista di attributi da escludere dal form (tutti gli altri attributi nel modello saranno mostrati). </p> +</div> + +<h4 id="Organizzare_la_vista_di_dettaglio_in_sezioni">Organizzare la vista di dettaglio in sezioni</h4> + +<p>È possibile aggiungere "sezioni" per raggruppare le informazioni relative al modello all'interno del modulo dettagli, utilizzando l'attributo <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets">fieldsets</a>.</p> + +<p>Nel modello <code>BookInstance</code> abbiamo delle informazioni sul libro (esempio <code>name</code>, <code>imprint</code>, ed <code>id</code>) e sullo stato (<code>status</code>, <code>due_back</code>). Possiamo aggiungere queste informazioni in differenti sezioni aggiungendo il testo in grassetto alla classe <code>BookInstanceAdmin.</code></p> + +<pre class="brush: python">@admin.register(BookInstance) +class BookInstanceAdmin(admin.ModelAdmin): + list_filter = ('status', 'due_back') + +<strong> fieldsets = ( + (None, { + 'fields': ('book', 'imprint', 'id') + }), + ('Availability', { + 'fields': ('status', 'due_back') + }), + )</strong></pre> + +<p>Ogni sezione avrà il suo titolo (o <code>None</code>, se non vuoi un titolo) e una tupla associata di campi in un dizionario - il formato è complicato da descrivere, ma abbastanza facile da capire se si guarda il frammento di codice immediatamente sopra.</p> + +<p>Ora vai a una vista di istanza di un libro nel tuo sito web; il modulo dovrebbe apparire come mostrato di seguito:</p> + +<p><img alt="Admin Site - Improved BookInstance Detail with sections" src="https://mdn.mozillademos.org/files/14029/admin_improved_bookinstance_detail_sections.png" style="border-style: solid; border-width: 1px; display: block; height: 580px; margin: 0px auto; width: 947px;"></p> + +<h3 id="Modifica_in_linea_dei_record_associati">Modifica in linea dei record associati</h3> + +<p>A volte può essere sensato essere in grado di aggiungere record associati nello stesso momento. Ad esempio, può avere senso avere sia le informazioni del libro che le informazioni sulle copie specifiche che si hanno nella stessa pagina di dettaglio.</p> + +<p>Puoi farlo dichiarando <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.inlines">inlines</a>, di tipo <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.TabularInline">TabularInline</a> (layout orizzontale) o <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.StackedInline">StackedInline</a> (layout verticale, come il modello di default). Puoi aggiungere l'informazione di <code>BookInstance</code> inline nel dettaglio di <code>Book</code> aggiungendo le linee di codice in grassetto vicino a <code>BookAdmin</code>:</p> + +<pre class="brush: python"><strong>class BooksInstanceInline(admin.TabularInline): + model = BookInstance</strong> + +@admin.register(Book) +class BookAdmin(admin.ModelAdmin): + list_display = ('title', 'author', 'display_genre') +<strong> inlines = [BooksInstanceInline]</strong> +</pre> + +<p>Ora vai a una vista per un libro nel tuo sito web: in basso ora dovresti vedere le istanze di libro relative a questo libro (immediatamente sotto i campi di genere del libro):<img alt="Admin Site - Book with Inlines" src="https://mdn.mozillademos.org/files/14033/admin_improved_book_detail_inlines.png" style="border-style: solid; border-width: 1px; display: block; height: 889px; margin: 0px auto; width: 937px;"></p> + +<p>In questo caso, tutto ciò che abbiamo fatto è dichiarare la nostra classe in linea tabellare, che aggiunge solo tutti i campi dal modello in linea. È possibile specificare tutti i tipi di informazioni aggiuntive per il layout, inclusi i campi da visualizzare, il loro ordine, se sono di sola lettura o meno, ecc. (Vedere <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.TabularInline">TabularInline</a> per ulteriori informazioni). </p> + +<div class="note"> +<p><strong>Note</strong>: Ci sono una serie di limitazioni importanti in questa funzionalità! Nello screenshot qui sopra abbiamo tre istanze di libri esistenti, seguite da tre segnaposti per le nuove istanze di libri (che sembrano molto simili!). Sarebbe meglio NON avere istanze di libri di riserva per impostazione predefinita e aggiungerle semplicemente con un link <strong>Add another Book instance</strong>, o listare le <code>BookInstance</code> come link non leggibili da qui. La prima opzione può essere eseguita impostando l'attributo <code>extra</code> su 0 nel modello <code>BooksInstanceInline</code>, provalo tu stesso</p> +</div> + +<h2 id="Prova_tu">Prova tu</h2> + +<p>Abbiamo imparato molto in questa sezione, quindi ora è il momento di provare alcune cose.</p> + +<ol> + <li>Per la list view di <code>BookInstance,</code> aggiungi un codice che permetta di mostrare libro, status, data di restituzione, e l'id (invece del testo di default restituito da <code>__str__()</code>).</li> + <li>Aggiungi una lista inline di oggetti <code>Book</code> inella scheda di dettaglio di <code>Author</code> usando lo stesso approccio che abbiamo utilizzato per <code>Book</code>/<code>BookInstance</code>.</li> +</ol> + +<ul> +</ul> + +<h2 id="Sommario">Sommario</h2> + +<p>Questo è tutto! Ora hai imparato come configurare il sito di amministrazione sia nella sua forma più semplice che migliorata, come creare un superutente e come navigare nel sito di amministrazione e visualizzare, eliminare e aggiornare i record. Lungo la strada hai creato un sacco di libri, pubblicazioni, generi e autori che saremo in grado di elencare e visualizzare una volta creati i nostri modelli e le nostre view.</p> + +<h2 id="Ulteriori_letture">Ulteriori letture</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/intro/tutorial02/#introducing-the-django-admin">Writing your first Django app, part 2: Introducing the Django Admin</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/contrib/admin/">The Django Admin site</a> (Django Docs)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> diff --git a/files/it/learn/server-side/django/authentication/index.html b/files/it/learn/server-side/django/authentication/index.html new file mode 100644 index 0000000000..a0e06c7252 --- /dev/null +++ b/files/it/learn/server-side/django/authentication/index.html @@ -0,0 +1,700 @@ +--- +title: 'Django Tutorial Part 8: User authentication and permissions' +slug: Learn/Server-side/Django/Authentication +tags: + - Articolo + - Forms + - Python + - Server + - Tutorial + - autenticazione + - django + - form + - sessione + - sessioni +translation_of: Learn/Server-side/Django/Authentication +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}</div> + +<p class="summary">In questo tutorial ti mostreremo come consentire agli utenti di accedere al tuo sito con i propri account e come controllare cosa possono fare e vedere in base al fatto che abbiano effettuato l'accesso e le relative autorizzazioni. Come parte di questa dimostrazione, estenderemo il sito Web LocalLibrary, aggiungendo pagine di accesso e disconnessione e pagine specifiche per utente e personale per la visualizzazione di libri presi in prestito.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td>Completare tutti i precedenti argomentioltre che il capitolo <a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a>.</td> + </tr> + <tr> + <th scope="row">Obiettivi:</th> + <td>Per capire come impostare e utilizzare l'autenticazione utente e le autorizzazioni.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica">Panoramica</h2> + +<p>Django fornisce un sistema di autenticazioni e permessi, costruito sulla base del framework delle sessioni discusso nel <a href="/en-US/docs/Learn/Server-side/Django/Sessions">precedente tutorial</a>, che consente di verificare le credenziali dell'utente e definire le azioni che ogni utente può eseguire. Il framework include modelli integrati per <code>utenti</code> e <code>gruppi </code>(un modo generico di applicare le autorizzazioni a più di un utente alla volta), permessi / flag che indicano se un utente può eseguire un'attività, formee viste per l'accesso degli utenti e strumenti di visualizzazione per limitare il contenuto.</p> + +<div class="note"> +<p><strong>Note</strong>: Secondo Django il sistema di autenticazione mira ad essere molto generico, e quindi non fornisce alcune funzionalità fornite in altri sistemi di autenticazione web. Le soluzioni per alcuni problemi comuni sono disponibili come pacchetti di terze parti. Ad esempio, limitazione dei tentativi di accesso e autenticazione contro terze parti (ad esempio OAuth).</p> +</div> + +<p>In questa esercitazione ti mostreremo come abilitare l'autenticazione utente nel sito Web LocalLibrary, creare le tue pagine di accesso e di disconnessione, aggiungere autorizzazioni ai tuoi modelli e controllare l'accesso alle pagine. Useremo l'autenticazione / le autorizzazioni per visualizzare elenchi di libri presi in prestito sia per gli utenti che per i bibliotecari.</p> + +<p>Il sistema di autenticazione è molto flessibile e, se lo desideri, puoi creare da zero URL, forms, viste e templates, basta chiamare l'API fornita per accedere all'utente.</p> + +<p>Tuttavia, in questo articolo, utilizzeremo le viste di autenticazione "immagazzinate" in Django e i moduli per le nostre pagine di accesso e di disconnessione. Avremo ancora bisogno di creare alcuni modelli, ma è abbastanza facile. Ti mostreremo anche come creare le autorizzazioni e controllare lo stato e le autorizzazioni di accesso sia nelle viste che nei modelli.</p> + +<h2 id="Abilitare_l'autenticazione">Abilitare l'autenticazione</h2> + +<p>L'autenticazione è stata abilitata automaticamente (nel tutorial 2), quindi non è necessario fare altro in questo punto.</p> + +<div class="note"> +<p><strong>Note</strong>: La configurazione necessaria è stata fatta per noi quando abbiamo creato l'app utilizzando il comando startproject di django-admin. Le tabelle del database per gli utenti e le autorizzazioni del modello sono state create quando abbiamo inizialmente chiamato <code>python manage.py migrate.</code></p> +</div> + +<p>La configurazione è visibile nelle sezioni INSTALLED_APPS e MIDDLEWARE del file di progetto (locallibrary / locallibrary / settings.py), come mostrato di seguito:</p> + +<pre class="brush: python">INSTALLED_APPS = [ + ... +<strong> 'django.contrib.auth', </strong>#Core authentication framework and its default models. +<strong> 'django.contrib.contenttypes', #</strong>Django content type system (allows permissions to be associated with models). + .... + +MIDDLEWARE = [ + ... +<strong> 'django.contrib.sessions.middleware.SessionMiddleware',</strong> #Manages sessions across requests + ... +<strong> 'django.contrib.auth.middleware.AuthenticationMiddleware',</strong> #Associates users with requests using sessions. + .... +</pre> + +<h2 id="Creazione_di_utenti_e_gruppi">Creazione di utenti e gruppi</h2> + +<p>Hai già creato il tuo primo utente quando abbiamo consultato il sito di amministrazione di Django nel tutorial 4 (questo era un superutente, creato con il comando python manage.py createsuperuser). Il nostro superutente è già autenticato e ha tutte le autorizzazioni, quindi avremo bisogno di creare un utente di prova per rappresentare un utente normale del sito. Useremo il sito di amministrazione per creare i nostri gruppi locali e gli accessi al sito Web, poiché è uno dei modi più rapidi per farlo.</p> + +<div class="note"> +<p>Note: Puoi anche creare utenti a livello di programmazione, come mostrato di seguito. Dovresti farlo, ad esempio, se sviluppi un'interfaccia per consentire agli utenti di iscriversi da soli (non si dovrebbe consentire agli utenti di accedere al sito di amministrazione).</p> + +<pre class="brush: python">from django.contrib.auth.models import User + +# Create user and save to the database +user = User.objects.create_user('myusername', 'myemail@crazymail.com', 'mypassword') + +# Update fields and then save again +user.first_name = 'John' +user.last_name = 'Citizen' +user.save() +</pre> +</div> + +<p>Di seguito creeremo prima un gruppo e poi un utente. Anche se non abbiamo ancora nessuna autorizzazione da aggiungere per i membri della nostra biblioteca, se è necessario in seguito, sarà molto più facile aggiungerli una volta al gruppo rispetto a ciascun membro. Avviare il server di sviluppo e accedere al sito di amministrazione nel proprio browser Web locale (<code>http:/127.0.0.1:8000/admin/</code>). Accedi al sito usando le credenziali per il tuo account superuser. Il livello principale del sito di amministrazione mostra tutti i tuoi modelli, ordinati per "Applicazione Django". Dalla sezione Autenticazione e autorizzazione, è possibile fare clic sui collegamenti Utenti o Gruppi per visualizzare i record esistenti.</p> + +<p><img alt="Admin site - add groups or users" src="https://mdn.mozillademos.org/files/14091/admin_authentication_add.png" style="border-style: solid; border-width: 1px; display: block; height: 364px; margin: 0px auto; width: 661px;"></p> + +<p>Creiamo un nuovo gruppo per i membri della libreria.</p> + +<ol> + <li>Fare clic sul pulsante Aggiungi (accanto a Gruppo) per creare un nuovo gruppo; inserire il nome "Membri libreria" per il gruppo.<img alt="Admin site - add group" src="https://mdn.mozillademos.org/files/14093/admin_authentication_add_group.png" style="border-style: solid; border-width: 1px; display: block; height: 561px; margin: 0px auto; width: 800px;"></li> + <li>Non abbiamo bisogno di permessi per il gruppo, quindi basta premere SALVA (verrai indirizzato a un elenco di gruppi).</li> +</ol> + +<p>Ora creiamo un utente:</p> + +<ol> + <li>Torna alla home page del sito admin.</li> + <li>Fai clic sul pulsante Aggiungi accanto a Utenti per aprire la finestra di dialogo Aggiungi utente.<img alt="Admin site - add user pt1" src="https://mdn.mozillademos.org/files/14095/admin_authentication_add_user_prt1.png" style="border-style: solid; border-width: 1px; display: block; height: 409px; margin: 0px auto; width: 800px;"></li> + <li>Immettere un nome utente e una password / conferma appropriati per l'utente del test</li> + <li>Premi <strong>SALVA</strong>.<br> + <br> + Il sito di amministrazione creerà il nuovo utente e ti condurrà immediatamente a una schermata Cambia utente in cui è possibile modificare il nome utente e aggiungere informazioni per i campi facoltativi del modello Utente. Questi campi includono il nome, il cognome, l'indirizzo e-mail e lo stato e le autorizzazioni dell'utente (deve essere impostato solo il flag Attivo). Più in basso è possibile specificare i gruppi e le autorizzazioni dell'utente e visualizzare date importanti relative all'utente (ad esempio la data di iscrizione e l'ultima data di accesso).<img alt="Admin site - add user pt2" src="https://mdn.mozillademos.org/files/14097/admin_authentication_add_user_prt2.png" style="border-style: solid; border-width: 1px; display: block; height: 635px; margin: 0px auto; width: 800px;"></li> + <li>Nella sezione Gruppi, seleziona Gruppo di membri della biblioteca dall'elenco di Gruppi disponibili, quindi premi la freccia destra tra le caselle per spostarlo nella casella Gruppi scelti.<img alt="Admin site - add user to group" src="https://mdn.mozillademos.org/files/14099/admin_authentication_user_add_group.png" style="border-style: solid; border-width: 1px; display: block; height: 414px; margin: 0px auto; width: 933px;"></li> + <li>Non abbiamo bisogno di fare altro qui, quindi seleziona di nuovo SALVA, per andare alla lista degli utenti.</li> +</ol> + +<p>Questo è tutto! Ora hai un account "membro della libreria normale" che potrai utilizzare per il test (una volta implementate le pagine per consentire loro di accedere).</p> + +<div class="note"> +<p><strong>Note</strong>: Dovresti provare a creare un altro utente membro della libreria. Inoltre, crea un gruppo per i bibliotecari e aggiungi un utente anche a quello!</p> +</div> + +<h2 id="Impostazione_delle_viste_di_autenticazione">Impostazione delle viste di autenticazione</h2> + +<p>Django fornisce quasi tutto ciò che è necessario per creare pagine di autenticazione per gestire login, logout e gestione delle password "out of the box". Ciò include un mappatore di URL, viste e forms, ma non include i template - dobbiamo creare il nostro! In questa sezione, mostreremo come integrare il sistema predefinito nel sito Web di LocalLibrary e creare i modelli. Li inseriremo negli URL principali del progetto.</p> + +<div class="note"> +<p><strong>Note</strong>: Non è necessario utilizzare alcun codice, ma è probabile che lo si desideri perché rende le cose molto più semplici. Dovrai quasi certamente cambiare il codice di gestione del modulo se cambi il tuo modello utente (un argomento avanzato!), Ma anche così, sarai comunque in grado di utilizzare le funzioni di visualizzazione in stock.</p> +</div> + +<div class="note"> +<p><strong>Note: </strong>In questo caso, potremmo inserire ragionevolmente le pagine di autenticazione, inclusi gli URL e i modelli, all'interno della nostra applicazione di catalogo. Tuttavia, se avessimo più applicazioni sarebbe meglio separare questo comportamento di accesso condiviso e renderlo disponibile su tutto il sito, è quello che faremo qui!</p> +</div> + +<h3 id="URL_del_progetto">URL del progetto</h3> + +<p>Aggiungi quanto segue alla fine del file urls.py del progetto (locallibrary / locallibrary / urls.py):</p> + +<pre class="brush: python">#Add Django site authentication urls (for login, logout, password management) +urlpatterns += [ + path('accounts/', include('django.contrib.auth.urls')), +] +</pre> + +<p>Vai a http://127.0.0.1:8000/accounts/ (nota la barra finale in avanti!) E Django mostrerà un errore dicendo che non è stato in grado di trovare questo URL e elenca tutti gli URL che ha provato. Da questo puoi vedere gli URL che funzioneranno, ad esempio:</p> + +<div class="note"> +<p><strong>Note: </strong>Usando il metodo precedente si aggiungono i seguenti URL con i nomi tra parentesi quadre, che possono essere utilizzati per invertire i mapping degli URL. Non è necessario implementare nient'altro: la mappatura degli URL di cui sopra esegue automaticamente la mappatura degli URL sottostanti.</p> + +<pre class="brush: python">accounts/ login/ [name='login'] +accounts/ logout/ [name='logout'] +accounts/ password_change/ [name='password_change'] +accounts/ password_change/done/ [name='password_change_done'] +accounts/ password_reset/ [name='password_reset'] +accounts/ password_reset/done/ [name='password_reset_done'] +accounts/ reset/<uidb64>/<token>/ [name='password_reset_confirm'] +accounts/ reset/done/ [name='password_reset_complete']</pre> +</div> + +<p>Ora prova a navigare verso l'URL di accesso (http://127.0.0.1:8000/accounts/login/). Ciò fallirà di nuovo, ma con un errore che ti dice che ci manca il modello richiesto (registration / login.html) sul percorso di ricerca del modello. Vedrai le seguenti righe elencate nella sezione gialla in alto:</p> + +<pre class="brush: python">Exception Type: TemplateDoesNotExist +Exception Value: <strong>registration/login.html</strong></pre> + +<p>Il passo successivo è creare una directory di registrazione sul percorso di ricerca e quindi aggiungere il file login.html.</p> + +<h3 id="Directory_template">Directory template</h3> + +<p>Gli URL (e le viste implicite) che abbiamo appena aggiunto si aspettano di trovare i loro template associati in una directory /<strong>registration</strong>/ da qualche parte nel percorso di ricerca dei template. Per questo sito, inseriremo le nostre pagine HTML nella cartella <strong>templates / registration /</strong>. Questa directory dovrebbe essere nella directory principale del progetto, cioè nella stessa directory delle cartelle del <strong>catalogo </strong>e della <strong>localibrary</strong>). Si prega di creare queste cartelle ora.</p> + +<div class="note"> +<p><strong>Note:</strong> La struttura delle cartelle dovrebbe essere:<br> + locallibrary (Django project folder)<br> + |_catalog<br> + |_locallibrary<br> + |_templates <strong>(new)</strong><br> + |_registration</p> +</div> + +<p>Per rendere queste directory visibili al caricatore di template (ovvero per inserire questa directory nel percorso di ricerca del modello), aprire le impostazioni del progetto (/locallibrary/locallibrary/settings.py) e aggiornare la riga 'DIRS' della sezione TEMPLATES come mostrato.</p> + +<pre class="brush: python">TEMPLATES = [ + { + ... +<strong> 'DIRS': [os.path.join(BASE_DIR, 'templates')],</strong> + 'APP_DIRS': True, + ... +</pre> + +<h3 id="Login_template">Login template</h3> + +<div class="warning"> +<p><strong>Importante</strong>: I modelli di autenticazione forniti in questo articolo sono una versione molto semplice / leggermente modificata dei modelli di login dimostrativi di Django. Potrebbe essere necessario personalizzarli per uso personale!</p> +</div> + +<p>Crea un nuovo file HTML chiamato /locallibrary/templates/registration/login.html e dagli il seguente contenuto:</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + +{% if form.errors %} + <p>Your username and password didn't match. Please try again.</p> +{% endif %} + +{% if next %} + {% if user.is_authenticated %} + <p>Your account doesn't have access to this page. To proceed, + please login with an account that has access.</p> + {% else %} + <p>Please login to see this page.</p> + {% endif %} +{% endif %} + +<form method="post" action="{% url 'login' %}"> +{% csrf_token %} +<table> + +<tr> + <td>\{{ form.username.label_tag }}</td> + <td>\{{ form.username }}</td> +</tr> + +<tr> + <td>\{{ form.password.label_tag }}</td> + <td>\{{ form.password }}</td> +</tr> +</table> + +<input type="submit" value="login" /> +<input type="hidden" name="next" value="\{{ next }}" /> +</form> + +{# Assumes you setup the password_reset view in your URLconf #} +<p><a href="{% url 'password_reset' %}">Lost password?</a></p> + +{% endblock %}</pre> + +<p id="sect1">Questo modello condivide alcune somiglianze con quelli che abbiamo visto prima: estende il nostro template di base e sovrascrive il blocco del contenuto. Il resto del codice è un codice di gestione della forma abbastanza standard, di cui parleremo in un successivo tutorial. Tutto quello che devi sapere per ora è che questo mostrerà un modulo in cui puoi inserire il tuo nome utente e password, e che se inserisci valori non validi ti verrà chiesto di inserire valori corretti quando la pagina si aggiorna.</p> + +<p>Naviga indietro alla login page (<a href="http://127.0.0.1:8000/accounts/login/">http://127.0.0.1:8000/accounts/login/</a>) una volta salvato il modello, dovresti vedere qualcosa del genere:</p> + +<p><img alt="Library login page v1" src="https://mdn.mozillademos.org/files/14101/library_login.png" style="border-style: solid; border-width: 1px; display: block; height: 173px; margin: 0px auto; width: 441px;"></p> + +<p>Se si tenta di accedere con esito positivo l'utente verrà reindirizzato a un'altra pagina (per impostazione predefinita sarà questa <a href="http://127.0.0.1:8000/accounts/profile/">http://127.0.0.1:8000/accounts/profile/</a>). Il problema qui è che, per impostazione predefinita, Django si aspetta che dopo l'accesso si desideri essere indirizzati a una pagina del profilo, che può essere o non essere il caso. Poiché non hai ancora definito questa pagina, riceverai un altro errore!</p> + +<p>Apri le impostazioni del progetto (/locallibrary/locallibrary/settings.py) e aggiungi il testo in basso alla fine. Ora quando accedi devi essere reindirizzato alla homepage del sito per impostazione predefinita.</p> + +<pre class="brush: python"># Redirect to home URL after login (Default redirects to /accounts/profile/) +LOGIN_REDIRECT_URL = '/' +</pre> + +<h3 id="Logout_template">Logout template</h3> + +<p>Se navighi verso l'URL di disconnessione (http://127.0.0.1:8000/accounts/logout/), vedrai qualche comportamento strano: l'utente verrà disconnesso, ma sarai indirizzato pagina di logout dell'Amministratore. Non è quello che vuoi, se non altro perché il link di accesso su quella pagina ti porta alla schermata di accesso dell'amministratore (e questo è disponibile solo per gli utenti che hanno il permesso is_staff).</p> + +<p>Crea e apri /locallibrary/templates/registration/logged_out.html. Copia il testo qui sotto:</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <p>Logged out!</p> + <a href="{% url 'login'%}">Click here to login again.</a> +{% endblock %}</pre> + +<p>Questo modello è molto semplice. Visualizza semplicemente un messaggio che informa che sei stato disconnesso e fornisce un collegamento che puoi premere per tornare alla schermata di accesso. Se vai di nuovo all'URL di logout dovresti vedere questa pagina:</p> + +<p><img alt="Library logout page v1" src="https://mdn.mozillademos.org/files/14103/library_logout.png" style="border-style: solid; border-width: 1px; display: block; height: 169px; margin: 0px auto; width: 385px;"></p> + +<h3 id="Password_reset_templates">Password reset templates</h3> + +<p>Il sistema di reimpostazione della password predefinito utilizza la posta elettronica per inviare all'utente un link di ripristino. È necessario creare moduli per ottenere l'indirizzo e-mail dell'utente, inviare l'e-mail, consentire loro di immettere una nuova password e prendere nota del completamento dell'intero processo.</p> + +<p>I seguenti modelli possono essere utilizzati come punto di partenza.</p> + +<h4 id="Password_reset_form">Password reset form</h4> + +<p>Questo è il modulo utilizzato per ottenere l'indirizzo e-mail dell'utente (per inviare l'e-mail di reimpostazione della password). Crea /locallibrary/templates/registration/password_reset_form.html e dagli il seguente contenuto:</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <form action="" method="post"> + {% csrf_token %} + {% if form.email.errors %} + \{{ form.email.errors }} + {% endif %} + <p>\{{ form.email }}</p> + <input type="submit" class="btn btn-default btn-lg" value="Reset password"> + </form> +{% endblock %} +</pre> + +<h4 id="Password_reset_eseguito">Password reset eseguito</h4> + +<p>Questo modulo viene visualizzato dopo che il tuo indirizzo email è stato raccolto. Crea /locallibrary/templates/registration/password_reset_done.html e dagli il seguente contenuto:</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p> +{% endblock %} +</pre> + +<h4 id="Password_reset_email">Password reset email</h4> + +<p>Questo modello fornisce il testo dell'email HTML contenente il link di ripristino che invieremo agli utenti. Crea /locallibrary/templates/registration/password_reset_email.html e dagli il seguente contenuto:</p> + +<pre class="brush: html">Someone asked for password reset for email \{{ email }}. Follow the link below: +\{{ protocol}}://\{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} +</pre> + +<h4 id="Password_reset_confirm">Password reset confirm</h4> + +<p>Questo modello fornisce il testo dell'email HTML contenente il link di ripristino che invieremo agli utenti. Crea /locallibrary/templates/registration/password_reset_email.html e dagli il seguente contenuto:</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + {% if validlink %} + <p>Please enter (and confirm) your new password.</p> + <form action="" method="post"> + {% csrf_token %} + <table> + <tr> + <td>\{{ form.new_password1.errors }} + <label for="id_new_password1">New password:</label></td> + <td>\{{ form.new_password1 }}</td> + </tr> + <tr> + <td>\{{ form.new_password2.errors }} + <label for="id_new_password2">Confirm password:</label></td> + <td>\{{ form.new_password2 }}</td> + </tr> + <tr> + <td></td> + <td><input type="submit" value="Change my password" /></td> + </tr> + </table> + </form> + {% else %} + <h1>Password reset failed</h1> + <p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p> + {% endif %} +{% endblock %} +</pre> + +<h4 id="Password_reset_completato">Password reset completato</h4> + +<p>Questo è l'ultimo modello di reimpostazione della password, che viene visualizzato per avvisarti quando la reimpostazione della password è riuscita. Crea /locallibrary/templates/registration/password_reset_complete.html e dagli il seguente contenuto:</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <h1>The password has been changed!</h1> + <p><a href="{% url 'login' %}">log in again?</a></p> +{% endblock %}</pre> + +<h3 id="Testare_la_nuova_pagina_di_autenticazione">Testare la nuova pagina di autenticazione</h3> + +<p>Ora che hai aggiunto la configurazione dell'URL e creato tutti questi modelli, le pagine di autenticazione ora dovrebbero funzionare!</p> + +<p>Puoi testare le nuove pagine di autenticazione usando questi URL:</p> + +<ul> + <li><a href="http://127.0.0.1:8000/accounts/login/">http://127.0.0.1:8000/accounts/login/</a></li> + <li><a href="http://127.0.0.1:8000/accounts/logout/">http://127.0.0.1:8000/accounts/logout/</a></li> +</ul> + +<p>Sarai in grado di testare la funzionalità di reimpostazione della password dal link nella pagina di accesso. Tieni presente che Django invierà solo e-mail di ripristino a indirizzi (utenti) già memorizzati nel suo database!</p> + +<div class="note"> +<p><strong>Note</strong>: Il sistema di reimpostazione della password richiede che il tuo sito Web supporti la posta elettronica, che va oltre lo scopo di questo articolo, quindi questa parte non funzionerà ancora. Per consentire il test, inserisci la seguente riga alla fine del tuo file settings.py. Questo registra tutte le e-mail inviate alla console (in questo modo è possibile copiare il link per la reimpostazione della password dalla console).</p> + +<pre class="brush: python">EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +</pre> + +<p>Vedi <a href="https://docs.djangoproject.com/en/2.1/topics/email/">Servizi email</a> (Django docs).</p> +</div> + +<h2 id="Test_verso_utenti_autenticati">Test verso utenti autenticati</h2> + +<p>Questa sezione esamina cosa possiamo fare per controllare selettivamente il contenuto che l'utente vede in base al fatto che sia connesso o meno.</p> + +<h3 id="Testing_nei_templates">Testing nei templates</h3> + +<p>Puoi ottenere informazioni sull'utente attualmente connesso nei modelli con la variabile di modello <code>\{{user}}</code> (questo viene aggiunto al contesto del modello per impostazione predefinita quando imposti il progetto come abbiamo fatto nel nostro scheletro).</p> + +<p>In genere testerai innanzitutto la variabile di modello <code>\{{user.is_authenticated}}</code> per determinare se l'utente è idoneo a vedere contenuti specifici. Per dimostrarlo, aggiorneremo la nostra barra laterale per visualizzare un collegamento "Accedi" se l'utente è disconnesso e un collegamento "Disconnetti" se sono connessi.</p> + +<p>Apri il template (<strong>/locallibrary/catalog/templates/base_generic.html</strong>) e copia il seguente testo nel blocco della barra laterale, immediatamente prima del tag <code>endblock</code>.</p> + +<pre class="brush: html"> <ul class="sidebar-nav"> + + ... + + <strong>{% if user.is_authenticated %}</strong> + <li>User: <strong>\{{ user.get_username }}</strong></li> + <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li> + <strong>{% else %}</strong> + <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li> + <strong>{% endif %} </strong> + </ul></pre> + +<p>Come puoi vedere, utilizziamo i tag if-else-endif per visualizzare in modo condizionale il testo in base al fatto che \{{user.is_authenticated}} sia vero. Se l'utente è autenticato, sappiamo che abbiamo un utente valido, quindi chiamiamo \{{user.get_username}} per visualizzare il loro nome.</p> + +<p>Creiamo gli URL di collegamento di accesso e di disconnessione utilizzando il tag <code>URL</code> e i nomi delle rispettive configurazioni di URL. Nota anche come abbiamo aggiunto <code>?next=\{{request.path}}</code>. Ciò che fa è aggiungere un parametro URL <font face="Consolas, Liberation Mono, Courier, monospace">next</font> contenente l'indirizzo (URL) della pagina corrente, alla fine dell'URL collegato. Dopo che l'utente ha effettuato correttamente l'accesso / uscita, le viste useranno questo valore "<code>next</code>" per reindirizzare l'utente alla pagina in cui hanno prima fatto clic sul collegamento login / logout.</p> + +<div class="note"> +<p><strong>Note</strong>: Provalo! Se ti trovi nella home page e fai clic su Accedi / Esci nella barra laterale, dopo il completamento dell'operazione dovresti tornare alla stessa pagina.</p> +</div> + +<h3 id="Testing_nelle_views">Testing nelle views</h3> + +<p>Se si utilizzano le viste basate sulle funzioni, il modo più semplice per limitare l'accesso alle funzioni è applicare il decoratore login_required alla funzione di visualizzazione, come mostrato di seguito. Se l'utente ha effettuato l'accesso, il codice di visualizzazione verrà eseguito normalmente. Se l'utente non ha effettuato l'accesso, verrà reindirizzato all'URL di accesso definito nelle impostazioni del progetto (settings.LOGIN_URL), passando il percorso assoluto corrente come parametro successivo. Se l'utente riesce ad accedere, verrà riportato a questa pagina, ma questa volta autenticato.</p> + +<pre class="brush: python">from django.contrib.auth.decorators import login_required + +@login_required +def my_view(request): + ...</pre> + +<div class="note"> +<p><strong>Note:</strong> Puoi fare lo stesso genere di cose manualmente testando su request.user.is_authenticated, ma il decoratore è molto più conveniente!</p> +</div> + +<p>Analogamente, il modo più semplice per limitare l'accesso agli utenti che hanno eseguito l'accesso nelle viste basate su classi è derivare da LoginRequiredMixin. Devi dichiarare questo mixin nella prima lista della superclasse, prima della classe della vista principale.</p> + +<pre class="brush: python">from django.contrib.auth.mixins import LoginRequiredMixin + +class MyView(LoginRequiredMixin, View): + ...</pre> + +<p>È inoltre possibile specificare un percorso alternativo per reindirizzare l'utente se non sono autenticati (login_url) e un nome parametro URL invece di "next" per inserire il percorso assoluto corrente (redirect_field_name).</p> + +<pre class="brush: python">class MyView(LoginRequiredMixin, View): + login_url = '/login/' + redirect_field_name = 'redirect_to' +</pre> + +<p>Per informazioni ulteriori, consultare <a href="https://docs.djangoproject.com/en/2.1/topics/auth/default/#limiting-access-to-logged-in-users">Django docs here</a>.</p> + +<h2 id="Esempio_—_Elencare_i_libri_correnti_dello_user">Esempio — Elencare i libri correnti dello user</h2> + +<p>Ora che sappiamo come limitare una pagina a un particolare utente, creiamo una vista dei libri che l'utente corrente ha preso in prestito.</p> + +<p>Sfortunatamente, non abbiamo ancora modo per gli utenti di prendere in prestito libri! Quindi, prima di poter creare l'elenco dei libri, estenderemo innanzitutto il modello <code>BookInstance </code>per supportare il concetto di prestito e utilizzare l'applicazione Django Admin per prestare diversi libri al nostro utente di test.</p> + +<h3 id="Models">Models</h3> + +<p>Innanzitutto, dovremo rendere possibile agli utenti un prestito di BookInstance (abbiamo già uno stato e una data di scadenza, ma non abbiamo ancora alcuna associazione tra questo modello e un utente. creane uno usando un campo ForeignKey (uno-a-molti). Abbiamo anche bisogno di un meccanismo semplice per verificare se un libro in prestito è in ritardo.</p> + +<p>Apri <strong>catalog/models.py</strong>, ed importa il modello <code>User</code> model da <code>django.contrib.auth.models:</code></p> + +<pre class="brush: python">from django.contrib.auth.models import User +</pre> + +<p>Successivamente, aggiungi il campo del mutuatario al modello BookInstance:</p> + +<pre class="brush: python">borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) +</pre> + +<p>Mentre siamo qui, aggiungiamo una <a href="https://docs.python.org/3/library/functions.html#property">property</a> che possiamo chiamare dai nostri modelli per capire se una determinata istanza di un libro è in ritardo. Mentre potremmo calcolare questo nel modello stesso, usare una proprietà come mostrato di seguito sarà molto più efficiente.</p> + +<p>Aggiungi questo da qualche parte vicino alla parte superiore del file:</p> + +<pre class="brush: python">from datetime import date</pre> + +<p class="brush: python">Ora aggiungi la seguente definizione di proprietà alla classe BookInstance:</p> + +<pre class="brush: python">@property +def is_overdue(self): + if self.due_back and date.today() > self.due_back: + return True + return False</pre> + +<div class="note"> +<p><strong>Note</strong>: Verifichiamo se due_back è vuoto prima di fare un confronto. Un campo vuoto forza Django a lanciare un errore invece di mostrare la pagina: i valori vuoti non sono confrontabili. Questo non è qualcosa che vorremmo far provare ai nostri utenti!</p> +</div> + +<p>Ora che abbiamo aggiornato i nostri modelli, dovremo effettuare nuove migrazioni sul progetto e quindi applicare tali migrazioni:</p> + +<pre class="brush: bash">python3 manage.py makemigrations +python3 manage.py migrate +</pre> + +<h3 id="Admin">Admin</h3> + +<p>Ora apri il <code>catalogo/admin.py</code> e aggiungi il campo del mutuatario alla classe <code>BookInstanceAdmin </code>sia in <code>list_display </code>che in <code>fielsets</code>, come mostrato di seguito. Questo renderà il campo visibile nella sezione Amministrazione, permettendoci di assegnare un <code>Utente</code> a una <code>BookInstance</code> quando necessario.</p> + +<pre class="brush: python">@admin.register(BookInstance) +class BookInstanceAdmin(admin.ModelAdmin): + list_display = ('book', 'status'<strong>, 'borrower'</strong>, 'due_back', 'id') + list_filter = ('status', 'due_back') + + fieldsets = ( + (None, { + 'fields': ('book','imprint', 'id') + }), + ('Availability', { + 'fields': ('status', 'due_back'<strong>,'borrower'</strong>) + }), + )</pre> + +<h3 id="Prestiamo_qualche_libro">Prestiamo qualche libro</h3> + +<p>Ora che è possibile noleggiare libri a un utente specifico, vai a prestare un certo numero di record su BookInstance. Imposta il campo preso in prestito all'utente di test, imposta lo stato "In prestito" e imposta le scadenze sia nel futuro che nel passato.</p> + +<div class="note"> +<p><strong>Note</strong>: Non spiegheremo nuovamente il processo, poiché sai già come utilizzare il sito di amministrazione!</p> +</div> + +<h3 id="View_dei_prestiti">View dei prestiti</h3> + +<p>Ora aggiungeremo una vista per ottenere l'elenco di tutti i libri che sono stati prestati all'utente corrente. Useremo la stessa visualizzazione di elenco generica basata sulla classe che conosciamo, ma questa volta importeremo e deriverà da LoginRequiredMixin, in modo che solo un utente che ha effettuato l'accesso possa chiamare questa vista. Scegliamo anche di dichiarare un template_name, piuttosto che usare l'impostazione predefinita, perché potremmo finire per avere alcuni elenchi diversi di record di BookInstance, con visualizzazioni e modelli diversi.</p> + +<p>Aggiungi quanto segue al catalog/views.py:</p> + +<pre class="brush: python">from django.contrib.auth.mixins import LoginRequiredMixin + +class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): + """Generic class-based view listing books on loan to current user.""" + model = BookInstance + template_name ='catalog/bookinstance_list_borrowed_user.html' + paginate_by = 10 + + def get_queryset(self): + return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')</pre> + +<p>Per limitare la nostra query solo agli oggetti BookInstance per l'utente corrente, re-implementiamo get_queryset () come mostrato sopra. Si noti che "o" è il codice memorizzato per "in prestito" e ordiniamo per data di restituzione, in modo che gli elementi più vecchi vengano visualizzati per primi.</p> + +<h3 id="Conf._URL_per_libri_in_prestito">Conf. URL per libri in prestito</h3> + +<p>Ora apri /catalog/urls.py e aggiungi un <code>path()</code> che punta alla vista precedente (puoi semplicemente copiare il testo qui sotto alla fine del file).</p> + +<pre class="brush: python">urlpatterns += [ + path('mybooks/', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'), +]</pre> + +<h3 id="Template_per_i_libri_in_prestito">Template per i libri in prestito</h3> + +<p>Ora, tutto ciò che dobbiamo fare per questa pagina è aggiungere un template. Per prima cosa, crea il file template <code>/catalog/templates/catalog/bookinstance_list_borrowed_user.html</code> e dagli il seguente contenuto:</p> + +<pre class="brush: python">{% extends "base_generic.html" %} + +{% block content %} + <h1>Borrowed books</h1> + + {% if bookinstance_list %} + <ul> + + {% for bookinst in bookinstance_list %} + <li class="{% if bookinst.is_overdue %}text-danger{% endif %}"> + <a href="{% url 'book-detail' bookinst.book.pk %}">\{{bookinst.book.title}}</a> (\{{ bookinst.due_back }}) + </li> + {% endfor %} + </ul> + + {% else %} + <p>There are no books borrowed.</p> + {% endif %} +{% endblock %}</pre> + +<p>Questo modello è molto simile a quelli che abbiamo creato precedentemente per gli oggetti Libro e Autore. L'unica cosa "nuova" qui è che controlliamo il metodo che abbiamo aggiunto nel modello (bookinst.is_overdue) e lo usiamo per cambiare il colore degli elementi scaduti.</p> + +<p>Quando il server di sviluppo è in esecuzione, dovresti essere in grado di visualizzare l'elenco per un utente che ha effettuato l'accesso nel tuo browser all'indirizzo http://127.0.0.1:8000/catalog/mybooks/. Provalo con il tuo utente loggato e disconnesso (nel secondo caso, dovresti essere reindirizzato alla pagina di login).</p> + +<h3 id="Aggiungi_l'elenco_alla_barra_laterale">Aggiungi l'elenco alla barra laterale</h3> + +<p>L'ultimo passo è aggiungere un link per questa nuova pagina nella barra laterale. Inseriremo questo nella stessa sezione in cui vengono visualizzate altre informazioni per l'utente che ha effettuato l'accesso. Aprire il modello di base (/locallibrary/catalog/templates/base_generic.html) e aggiungere la linea in grassetto alla barra laterale come mostrato.</p> + +<pre class="brush: python"> <ul class="sidebar-nav"> + {% if user.is_authenticated %} + <li>User: \{{ user.get_username }}</li> +<strong> <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li></strong> + <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li> + {% else %} + <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li> + {% endif %} + </ul> +</pre> + +<h3 id="Che_cosa_vedo">Che cosa vedo?</h3> + +<p>Quando un utente ha effettuato l'accesso, vedrà il link I miei prestiti nella barra laterale e l'elenco dei libri visualizzati come segue (il primo libro non ha una data di scadenza, che è un bug che speriamo di risolvere in un tutorial successivo!).</p> + +<p><img alt="Library - borrowed books by user" src="https://mdn.mozillademos.org/files/14105/library_borrowed_by_user.png" style="border-style: solid; border-width: 1px; display: block; height: 215px; margin: 0px auto; width: 530px;"></p> + +<h2 id="Permessi">Permessi</h2> + +<p>Le autorizzazioni sono associate ai modelli e definiscono le operazioni che possono essere eseguite su un'istanza del modello da un utente che dispone dell'autorizzazione. Per impostazione predefinita, Django aggiunge automaticamente autorizzazioni di aggiunta, modifica ed eliminazione a tutti i modelli, che consentono agli utenti con le autorizzazioni di eseguire le azioni associate tramite il sito di amministrazione. È possibile definire le proprie autorizzazioni per i modelli e concederle ad utenti specifici. È inoltre possibile modificare le autorizzazioni associate a diverse istanze dello stesso modello.</p> + +<p>I test sulle autorizzazioni nelle viste e nei modelli sono quindi molto simili per il test sullo stato di autenticazione (e infatti, il test per un'autorizzazione verifica anche l'autenticazione).</p> + +<h3 id="Models_2">Models</h3> + +<p>Dfeinire permessi è un'azione svolta tramite la sezione "<code>class Meta</code>", utilizzando il campo <code>permissions</code>. È possibile specificare tutte le autorizzazioni necessarie in una tupla, ogni autorizzazione viene definita in una tupla nidificata contenente il nome di autorizzazione e il valore di visualizzazione delle autorizzazioni. Ad esempio, potremmo definire un'autorizzazione per consentire a un utente di contrassegnare che un libro è stato restituito come mostrato:</p> + +<pre class="brush: python">class BookInstance(models.Model): + ... + class Meta: + ... +<strong> permissions = (("can_mark_returned", "Set book as returned"),) </strong> </pre> + +<p>Potremmo quindi assegnare l'autorizzazione a un gruppo "Bibliotecario" nel sito di amministrazione. Apri il catalogo / models.py e aggiungi l'autorizzazione come mostrato sopra. Dovrai rieseguire le tue migrazioni (esegui <code>python3 manage.py makemigrations</code> e <code>python3 manage.py migrate</code>) per aggiornare il database.</p> + +<h3 id="Templates">Templates</h3> + +<p>I permessi correnti di un utente sono storati in una variabile <code>\{{ perms }}</code>. Puoi verificare se l'utente corrente ha un permesso particolare usando il nome specifico della variabile all'interno della "app" Django associata, ad es. <code>\{{ perms.catalog.can_mark_returned }}</code> sarà <code>True</code> se lo user ha i permessi, e <code>False</code> altrimenti. Tipicamente testiamo i permessi utilizzando il tag <code>{% if %}</code> come mostrato:</p> + +<pre class="brush: python">{% if perms.catalog.can_mark_returned %} + <!-- We can mark a BookInstance as returned. --> + <!-- Perhaps add code to link to a "book return" view here. --> +{% endif %} +</pre> + +<h3 id="Views">Views</h3> + +<p>Le autorizzazioni possono essere verificate nella funzione vista utilizzando il decoratore <code>permission_required</code> o in una visualizzazione basata su classi che utilizza <code>PermissionRequiredMixin</code>. Lo schema e il comportamento sono gli stessi dell'autenticazione di accesso, anche se, naturalmente, è possibile che sia necessario aggiungere multiple autorizzazioni.</p> + +<p>Decoratore:</p> + +<pre class="brush: python">from django.contrib.auth.decorators import permission_required + +@permission_required('catalog.can_mark_returned') +@permission_required('catalog.can_edit') +def my_view(request): + ...</pre> + +<p>Views.</p> + +<pre class="brush: python">from django.contrib.auth.mixins import PermissionRequiredMixin + +class MyView(PermissionRequiredMixin, View): + permission_required = 'catalog.can_mark_returned' + # Or multiple permissions + permission_required = ('catalog.can_mark_returned', 'catalog.can_edit') + # Note that 'catalog.can_edit' is just an example + # the catalog application doesn't have such permission!</pre> + +<h3 id="Esempio">Esempio</h3> + +<p>Non aggiorneremo la LocalLibrary qui; forse nel prossimo tutorial!</p> + +<h2 id="Prova_tu">Prova tu</h2> + +<p>In precedenza in questo articolo, vi abbiamo mostrato come creare una pagina per l'utente corrente che elenca i libri che hanno preso in prestito. La sfida ora è creare una pagina simile che sia visibile solo per i bibliotecari, che mostri tutti i libri presi in prestito e che includa il nome di ciascun mutuatario.</p> + +<p>Dovresti essere in grado di seguire lo stesso schema dell'altra vista. La differenza principale è che dovrai limitare la visualizzazione solo ai bibliotecari. Puoi farlo a seconda che l'utente sia un membro del personale (decoratore di funzioni: <code>staff_member_required</code>, template variabile: <code>user.is_staff</code>) ma ti raccomandiamo invece di utilizzare il permesso <code>can_mark_returned</code> e <code>PermissionRequiredMixin</code>, come descritto sopra nella sezione precedente.</p> + +<div class="warning"> +<p><strong>Importante</strong>: Ricordati di non utilizzare il superutente per i test basati sulle autorizzazioni (i controlli delle autorizzazioni restituiscono sempre true per i superutenti, anche se non è ancora stata definita un'autorizzazione!). Invece, crea un utente di libreria e aggiungi il permesso richiesto.</p> +</div> + +<p>Quando hai finito, la tua pagina dovrebbe apparire come lo screenshot qui sotto.</p> + +<p><img alt="All borrowed books, restricted to librarian" src="https://mdn.mozillademos.org/files/14115/library_borrowed_all.png" style="border-style: solid; border-width: 1px; display: block; height: 283px; margin: 0px auto; width: 500px;"></p> + +<ul> +</ul> + +<h2 id="Sommario">Sommario</h2> + +<p>Lavoro eccellente: ora hai creato un sito Web in cui i membri della biblioteca possono accedere e visualizzare il proprio contenuto e che i bibliotecari (con il permesso corretto) possono utilizzare per visualizzare tutti i libri in prestito ei loro mutuatari. Al momento stiamo ancora solo visualizzando i contenuti, ma gli stessi principi e tecniche sono utilizzati quando si desidera iniziare a modificare e aggiungere dati.</p> + +<p>Nel nostro prossimo articolo, vedremo come è possibile utilizzare i moduli di Django per raccogliere input dell'utente e quindi iniziare a modificare alcuni dei nostri dati memorizzati.</p> + +<h2 id="Vedi_anche">Vedi anche</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/auth/">User authentication in Django</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/auth/default//">Using the (default) Django authentication system</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/intro/#decorating-class-based-views">Introduction to class-based views > Decorating class-based views</a> (Django docs)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}</p> + +<p> </p> + +<h2 id="In_questo_modulo">In questo modulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> + +<p> </p> diff --git a/files/it/learn/server-side/django/development_environment/index.html b/files/it/learn/server-side/django/development_environment/index.html new file mode 100644 index 0000000000..75d6cd9ffb --- /dev/null +++ b/files/it/learn/server-side/django/development_environment/index.html @@ -0,0 +1,415 @@ +--- +title: Impostazione ambiente di sviluppo per Django +slug: Learn/Server-side/Django/development_environment +tags: + - Ambiente di sviluppo + - Intro + - Principiante + - Python + - django +translation_of: Learn/Server-side/Django/development_environment +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}</div> + +<p class="summary">Ora che sai a cosa serve Django, ti mostreremo come creare e testare un ambiente di sviluppo per Django su Windows, Linux (Ubuntu), e macOS — qualsiasi sistema operativo, comune, tu stia usando, questo articolo ti darà tutto il necessario per iniziare a sviluppare applicazioni Django.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td>Saper aprire un terminale / linea di comando. Saper installare un pacchetto software sul tuo sistema operativo.</td> + </tr> + <tr> + <th scope="row">Obiettivo:</th> + <td>Avere un ambiente di sviluppo per Django (2.0) sul tuo computer.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica_sullambiente_di_sviluppo_per_Django">Panoramica sull'ambiente di sviluppo per Django</h2> + +<p>Django rende molto semplice impostare il tuo computer per iniziare lo sviluppo di web application. Questa sezione spiega cosa avrai nel tuo ambiente di sviluppo, e fornirà una panoramica delle possibili impostazioni e configurazioni. Il resto dell'articolo spiega il metodo <em>raccomandato</em> per installare l'ambiente di sviluppo di Django su Ubuntu, macOS, e Windows, ed infine come testarlo.</p> + +<h3 id="Cosa_è_lambiente_di_sviluppo_Django">Cosa è l'ambiente di sviluppo Django?</h3> + +<p>L'ambiente di sviluppo è un'installazione di Django sul tuo computer che puoi usare per sviluppare e testare applicazioni Django prima di metterle in ambiente di produzione.</p> + +<p>Gli strumenti principali che Django fornisce sono una serie di script Python per creare e lavorare sui progetti Django, insieme ad un semplice <em>webserver</em> di sviluppo che puoi usare per testare localmente (ad es. sul tuo computer, non su un web server esterno) le applicazione web di Django usando un browser sul tuo computer.</p> + +<p>Ci sono altri strumenti periferici, che formano l'ambiente di sviluppo, che non tratteremo qui. Questi includono cose come <a href="/en-US/docs/Learn/Common_questions/Available_text_editors">editor di testo</a> o IDE per modificare il codice, e uno strumento per gestire il controllo di versione come <a href="https://git-scm.com/">Git</a> per gestire in modo affidabile differenti versioni del tuo codice. Assumiamo che tu abbia già un editor di testo installato.</p> + +<h3 id="Quali_sono_le_opzioni_di_setup_di_Django">Quali sono le opzioni di setup di Django?</h3> + +<p>Django è estremamente flessibile in termni di come e dove può essere installato e configurato. Django può essere:</p> + +<ul> + <li>installato su differenti sistemi operativi.</li> + <li>usato con Python 3 e Python 2.</li> + <li>installato dal codice sorgente, da Python Package Index (PyPi) e in molti altri casi installato dal package manager presente nel sistema operativo installato.</li> + <li>configurato per usare uno o più database, che potrebbero necessitare di essere installati e configurati separatamente.</li> + <li>eseguito sull'ambiente Python di sistema o in un virtual enviroment Python separato.</li> +</ul> + +<p>Ognuna di queste opzioni richiede configurazioni e setup leggermente diverse. La seguente sottosezione spiega alcune di queste possibilità. Per il resto dell'articolo mostreremo come impostare Django in un piccolo numero di sistemi operativi, e questo setup sarà assunto valido per tutto il modulo.</p> + +<div class="note"> +<p><strong>Nota</strong>: Altri possbili metodi di installazione sono descritti nella documentazione ufficiale di Django. Diamo i link al <a href="#furtherreading">documento appropriato</a> più avanti.</p> +</div> + +<h4 id="Quali_sistemi_operativi_sono_supportati">Quali sistemi operativi sono supportati?</h4> + +<p>Le applicazioni Django possono essere eseguite su quasi tutte le macchine che possono eseguire il linguaggio Python 3: Windows, macOS, Linux/Unix, Solaris, per nominarne alcuni. Quasi tutti i computer hanno le caratteristiche per eseguire Django durante lo sviluppo.</p> + +<p>In questo articolo tratteremo dei casi Windows, macOS, e Linux/Unix.</p> + +<h4 id="Quale_versione_di_Python_dovrei_usare">Quale versione di Python dovrei usare?</h4> + +<p>Django esegue sopra Python, e può essere usato sia con Python 2 o Python 3 (o entrambi). Quando scegli una versione devi stare attento che:</p> + +<ul> + <li>Python 2 è la versione legacy del linguaggio e non riceve nessuna novità ma ha un repository enorme per librerie di terze parti da usate da sviluppatori ( alcune delle quali sono sono disponbili per Python 3).</li> + <li>Python 3 è un aggiornamento di Python 2 che, anche se simile, è più consistente e semplice da usare. Python 3 è il futuro del Python e contina ad evolversi.</li> + <li>è possibile usare entrambe le versioni usando librerie di compatibilità (come <a href="http://pythonhosted.org/six/">six</a>), tuttavia non senza un ulteriore sforzo.</li> +</ul> + +<ul> +</ul> + +<div class="note"> +<p><strong>Nota</strong>: Storicamente Python 2 era la scelta più realistica, perché poche delle librerie di terze parti erano disponibili per Python 3. Il trend corrente è che molti dei nuovi package su <a href="https://pypi.python.org/pypi">Python Package Index</a> (PyPi) supportano entrambe le versioni di Python. Mentre esistono ancora moli package che sono disponibili esclusivamente per Python 2, scegliere Python 3 è ora una scelta fattibile.</p> +</div> + +<p>Ti raccomandiamo di usare l'ultima versione di Python 3 a meno che il sito non dipenda da librerie di terze parti disponibili solo per Python 2.</p> + +<p>Questo articolo spiegherà come installare un ambiente per Python 3 (il setup equivalente per Python 2 dovrebbe essere molto simile).</p> + +<h4 id="Dove_posso_scaricare_Django">Dove posso scaricare Django?</h4> + +<p>Ci sono tre posti dove scaricare Django:</p> + +<ul> + <li>Il Python Package Repository (PyPi), usando <em>pip</em>. Questo è il modo migliore per avere l'ultima versione stabile di Django.</li> + <li>Installa una versione dal tuo gestore di pacchetti. Distribuzioni di Django incluse nei sistemi operativi offrono un sistema di installazione familiare. Nota che le versioni dei pacchetti possono essere piuttosto vecchie, e possono essere installati solo quelli dell'ambiente Python (che potrebbe non essere quello che volete).</li> + <li>Installarlo da codice sorgente. Puoi prendere e installare l'ultima versione di Python da codice sorgente. Questo non è raccomandato per i novizi, ma sarà necessario quando sarai pronto a contribuire a Django.</li> +</ul> + +<p>Questo articolo mostra come installare Django da PyPi, in modo da avere l'ultima versione stabile.</p> + +<h4 id="Quale_database">Quale database?</h4> + +<p>Django supporta 4 database principali (PostgreSQL, MySQL, Oracle e SQLite), e ci sono librerie che forniscono vari livelli di supporto ai più popolari database SQL e NOSQL. Ti raccomandiamo di scegliere lo stesso database in sviluppo e in produzione (nonostante Django astragga le differenze tra i database usando il suo Object-Relational Mapper (ORM), ci sono <a href="https://docs.djangoproject.com/en/1.10/ref/databases/">potenziali problemi</a> che è bene evitare).</p> + +<p>Per questo articolo (e molti altri di questo modulo) useremo <em>SQLite</em>,che memorizza i dati in un file. SQLite è da intendersi come un database leggero senza supporto per un alto livello di concorrenza. Tutta via è una scelta eccellente per applicazioni che fanno principalmente sola lettura.</p> + +<div class="note"> +<p><strong>Nota</strong>: Django è configurato per usare SQLite di default quando fai partire il tuo progetto usando gli strumenti standard (<em>django-admin</em>). E' una scelta ottima quando stai iniziando perchè non necessita di configurazioni. </p> +</div> + +<h4 id="Installare_da_sistema_o_in_un_ambiente_virtuale_di_Python">Installare da sistema o in un ambiente virtuale di Python?</h4> + +<p>Quando installi Python 3 sul tuo computer hai un singolo ambiente globale (inteso come insieme di pacchetti installati) per il tuo codice Python, che puoi gestire usando <em>pip3</em>. Puoi installare qualsiasi pacchetto Python tu voglia, ma puoi installarne solo una certa versione alla volta. Questo vuol dire che ogni cambiamento che fai in una applicazione Python potenzialmente può aver effetto sulle altre, e quindi puoi avere una sola versione di Django alla volta.</p> + +<p>Sviluppatori Python/Django con un po di esperienza spesso decidono di eseguire le loro applicazioni in un <em>ambiente Python virtuale.</em> Questo permette a gli sviluppatori di avere diversi ambienti di Django in un singolo computer, permettendogli di creare nuovi siti web (usando l'ultima versione corrente di Django) mentre mantengono siti web che fanno affidamento a versioni più vecchie. Gli sviluppatori del team di Django raccomandano di usare questi ambienti virtuali!</p> + +<p>Quando si sta iniziando l'approccio iniziale che usate non è importante. Sebbene l'installazione sia un po' più facile, abbiamo deciso di mostrarti come installare Django direttamente sul Python 3 di sistema.</p> + +<div class="warning"> +<p><strong>Importante</strong>: Il resto dell'articolo mostra come impostare Django in un ambiente con Python 3, su Ubuntu Linux, Mac OS X, e Windows 10.</p> +</div> + +<h2 id="Installare_Python_3">Installare Python 3</h2> + +<p>Per usare Django devi installare <em>Python 3</em> sul tuo sistema operativo. Avrai bisogno anche di <a href="https://pypi.python.org/pypi">Python Package Index</a> — <em>pip3</em> — che viene usato per gestire (installare, aggiornare, e rimuovere) package/librerie Python usate da Django altre tue applicazioni Python.</p> + +<p>Questa sezione mostra brevemente come puoi controllare quali versioni sono presenti, e se necessario installare una nuova versione, per Ubuntu Linux 16.04, Mac OS X, e Windows 10.</p> + +<div class="note"> +<p><strong>Nota</strong>: In base alla tua piattaforma, potrebbe essere possibile installare Python/pip dal gestore di pacchetti del sistema operativo o tramite altri meccanismi. Per molte piattaforme puoi scaricare i file di installazione da <a href="https://www.python.org/downloads/">https://www.python.org/downloads/</a> usando le istruzioni per il vostro sistema operativo.</p> +</div> + +<h3 id="Ubuntu_16.04">Ubuntu 16.04</h3> + +<p>Ubuntu Linux include Python 3 di default. Puoi aver conferma di questo eseguendo il seguente comando nel terminale bash:</p> + +<pre class="brush: bash notranslate">python3 -V + Python 3.5.2</pre> + +<p>Tuttavia il Python Package Index di cui hai bisogno per installare package Python 3 (incluso Django) <strong>non</strong> è disponibile di default. Puoi installare pip3 dal terminale bash usando:</p> + +<pre class="brush: bash notranslate">sudo apt-get install python3-pip +</pre> + +<h3 id="Mac_OS_X">Mac OS X</h3> + +<p>Mac OS X "El Capitan" non include Python 3. Puoi averne conferma eseguendo il seguente comando nel terminale bash:</p> + +<pre class="brush: bash notranslate">python3 -V + -bash: python3: command not found</pre> + +<p>Puoi installare facilmente Python 3 (inseme a <em>pip3</em>) da <a href="https://www.python.org/">python.org</a>:</p> + +<ol> + <li>Scarica l'installer: + <ol> + <li>Vai su <a href="https://www.python.org/downloads/">https://www.python.org/downloads/</a></li> + <li>Seleziona <strong>Download Python 3.5.2</strong> (il <em>minor</em> del numero di versione esatto può essere differente).</li> + </ol> + </li> + <li>Cercare il file usando <em>Finder</em>, fai doppio-click sul file. Segui le istruzioni dell'installazione.</li> +</ol> + +<p>Per essere sicuro della corretta installazione di <em>Python 3</em>:</p> + +<pre class="brush: bash notranslate">python3 -V + Python 3.5.20 +</pre> + +<p>Similmente puoi controllare che <em>pip3</em> sia installato guardando i package disponibili:</p> + +<pre class="brush: bash notranslate">pip3 list</pre> + +<h3 id="Windows_10">Windows 10</h3> + +<p>Windows non include Python di default, ma puoi installarlo facilmente (insieme a <em>pip3</em>) da<a href="https://www.python.org/"> python.org</a>:</p> + +<ol> + <li>Scarica l'installer: + <ol> + <li>Vai su <a href="https://www.python.org/downloads/">https://www.python.org/downloads/</a></li> + <li>Seleziona <strong>Download Python 3.5.2</strong> (il <em>minor</em> del numero di versione esatto può essere differente).</li> + </ol> + </li> + <li>Installa Python facendo double-click sul file scaricato e segui le istruzioni</li> +</ol> + +<p>Puoi verificare che Python sia stato installato correttamente digitando sulla linea di comando:</p> + +<pre class="brush: bash notranslate">py -3 -V + Python 3.5.2 +</pre> + +<p>L'installer di Windows contiene <em>pip3</em> (Python package manager) di default. Puoi vedere la lista dei pacchetti installati usando:</p> + +<pre class="brush: bash notranslate">pip3 list +</pre> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: L'installer dovrebbe essere impostato ovunque tu voglia, perché il comando di sopra funzioni. Se tuttavia dovessi ottenere un messaggio che Python non può essere trovato, potresti aver dimenticato di aggiungerlo al path di sistema. Puoi farlo eseguendo di nuovo l'installer, scegliendo "Modify" e selezionando "Add Pyhton to environment variables" nella seconda pagina.</p> +</div> + +<h2 id="Utilizzare_Django_allinterno_di_un_ambiente_virtuale_Python">Utilizzare Django all'interno di un ambiente virtuale Python</h2> + +<p>Le librerie che useremo per la creazione dei nostri ambienti virtuali sono <a href="https://virtualenvwrapper.readthedocs.io/en/latest/index.html">virtualenvwrapper</a> (Linux e macOS) e <a href="https://pypi.python.org/pypi/virtualenvwrapper-win">virtualenvwrapper-win</a> (Windows), che a loro volta utilizzano entrambi il tool <a href="https://developer.mozilla.org/en-US/docs/Python/Virtualenv">virtualenv</a>. Gli strumenti wrapper creano un'interfaccia coerente per gestire interfacce su tutte le piattaforme.</p> + +<h3 id="Installare_il_software_virtual_environment">Installare il software virtual environment</h3> + +<h4 id="Setup_del_virtual_environment_su_Ubuntu">Setup del virtual environment su Ubuntu</h4> + +<p>Dopo l'installazione di Python e pip puoi installare <em>virtualenvwrapper</em> (che comprende <em>virtualenv</em>). La guida ufficiale di installazione si può trovare <a href="http://virtualenvwrapper.readthedocs.io/en/latest/install.html">qui</a>, oppure seguire le istruzioni sotto.</p> + +<p>Installare il tool utilizzando <em>pip3</em>:</p> + +<pre class="notranslate"><code>sudo pip3 install virtualenvwrapper</code> +</pre> + +<p>Poi aggiungi le seguenti linee alla fine del tuo file di startup della shell (questo è un file nascosto chiamato <strong>.bashrc</strong> nella tua directory home). Questo imposta la posizione in cui dovrebbero vivere i virtual environment, la posizione delle tue directory di sviluppo dei progetti e la posizione dello script installato con questo pacchetto:</p> + +<pre class="notranslate"><code>export WORKON_HOME=$HOME/.virtualenvs +export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 +export VIRTUALENVWRAPPER_VIRTUALENV_ARGS=' -p /usr/bin/python3 ' +export PROJECT_HOME=$HOME/Devel +source /usr/local/bin/virtualenvwrapper.sh</code> +</pre> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Le variabili <code>VIRTUALENVWRAPPER_PYTHON</code> e <code>VIRTUALENVWRAPPER_VIRTUALENV_ARGS</code> puntano alla posizione di installazione normale per Python3, e <code>source /usr/local/bin/virtualenvwrapper.sh</code> punta alla posizione normale dello script <code>virtualenvwrapper.sh</code>. Se il <em>virtualenv</em> non funziona quando lo si testa, una cosa da controllare è che Python e lo script siano nella posizione attesa (e quindi modificare il file di startup adeguatamente).<br> + <br> + Puoi trovare le posizioni corrette per il tuo sistema utilizzando i comandi <code>which virtualenvwrapper.sh</code> e <code>which python3</code>.</p> +</div> + +<p>Poi ricarica il file di startup eseguendo il seguente comando nel terminale:</p> + +<pre class="notranslate"><code>source ~/.bashrc</code></pre> + +<p>A questo punto si dovrebbe vedere un blocco di script che viene eseguito come mostrato sotto:</p> + +<pre class="notranslate"><code>virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/premkproject +virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postmkproject +... +virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/preactivate +virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postactivate +virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/get_env_details</code></pre> + +<p>Ora puoi creare un nuovo ambiente virtuale con il comando <code>mkvirtualenv</code>.</p> + +<h4 id="Setup_di_un_ambiente_virtuale_su_macOS">Setup di un ambiente virtuale su macOS</h4> + +<p>Impostare un <em>virtualenvwrapper</em> su macOS è quasi esattamente la stessa cosa che su Ubuntu (ancora una volta, si possono seguire le istruzioni o della guida <a href="http://virtualenvwrapper.readthedocs.io/en/latest/install.html">official installation</a> oppure quelle qui sotto.</p> + +<p>Installare <em>virtualenvwrapper</em> (e costruire <em>virtualenv</em>) utilizzando <em>pip</em> come mostrato.</p> + +<pre class="notranslate"><code>sudo pip3 install virtualenvwrapper</code></pre> + +<p>Poi aggiungi le seguenti linee alla fine del file di startup della shell.</p> + +<pre class="notranslate"><code>export WORKON_HOME=$HOME/.virtualenvs +export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 +export PROJECT_HOME=$HOME/Devel +source /usr/local/bin/virtualenvwrapper.sh</code></pre> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: la variabile <code>VIRTUALENVWRAPPER_PYTHON</code> punta alla normale posizione di installazione per Python3, e <code>source /usr/local/bin/virtualenvwrapper.sh</code> punta alla normale posizione dello script <code>virtualenvwrapper.sh</code>. Se il <em>virtualenv</em> non funziona quando lo si testa, una cosa da controllare è che Python e lo script siano nella posizione attesa (e poi modificare il file di startup adeguatamente).</p> + +<p>Per esempio, un test di installazione su macOS avrà le seguenti linee necessarie nel file di startup:</p> + +<pre class="notranslate"><code>export WORKON_HOME=$HOME/.virtualenvs +export VIRTUALENVWRAPPER_PYTHON=/Library/Frameworks/Python.framework/Versions/3.7/bin/python3 +export PROJECT_HOME=$HOME/Devel +source /Library/Frameworks/Python.framework/Versions/3.7/bin/virtualenvwrapper.sh</code></pre> + +<p>Puoi trovare le posizioni corrette per il tuo sistema utilizzando i comandi <code>which virtualenvwrapper.sh</code> e <code>which python3</code>.</p> +</div> + +<p>Queste sono le stesse linee come per Ubuntu, ma il file di startup è il file nascosto chiamato (diversamente) <strong>.bash_profile</strong> nella tua cartella home.</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Se non riesci a trovare <strong>.bash_profile</strong> per modificarlo nel finder, puoi anche aprirlo nel terminale utilizzando nano.</p> + +<p>I comandi saranno simili a questi:</p> + +<pre class="notranslate"><code>cd ~ # Navigate to my home directory +ls -la #List the content of the directory. YOu should see .bash_profile +nano .bash_profile # Open the file in the nano text editor, within the terminal +# Scroll to the end of the file, and copy in the lines above +# Use Ctrl+X to exit nano, Choose Y to save the file.</code> +</pre> +</div> + +<p>Poi ricarica il file di startup facendo la seguente chiamata nel terminale:</p> + +<pre class="notranslate"><code>source ~/.bash_profile</code></pre> + +<p>A questo punto, si dovrebbero vedere una serie di script che vengono eseguiti (gli stessi script dell'installazione in Ubuntu). Ora dovresti essere in grado di creare un nuovo virtual environment con il comando <code>mkvirtualenv</code>.</p> + +<h4 id="Setup_del_virtual_environment_Windows_10">Setup del virtual environment Windows 10</h4> + +<p>Installare <a href="https://pypi.python.org/pypi/virtualenvwrapper-win">virtualenvwrapper-win</a> è anche più semplice di settare <em>virtualenvwrapper</em> perché non hai bisogno di configurare dove i tool memorizzano l'informazione dei virtual environment (c'è un valore di dafault). Tutto ciò che devi fare è eseguire il seguente comando nel prompt dei comandi:</p> + +<pre class="notranslate"><code>pip3 install virtualenvwrapper-win</code></pre> + +<p>Ora sei in grado di creare un nuovo virtual environment con il comando <code>mkvirtualenv</code>.</p> + +<h3 id="Creazione_di_un_virtual_environment">Creazione di un virtual environment</h3> + +<p>Una volta installato <em>virtualenvwrapper</em> o <em>virtualenvwrapper-win</em> allora lavorare con virtual environment è molto simile su tutte le piattaforme.</p> + +<p>Ora puoi creare un nuovo virtual environment col comando <code>mkvirtualenv</code> . Quando questo comando viene eseguito vedrai l'ambiente che viene settato (ciò che vedrai è leggermente specifico della piattaforma). Quando il comando viene completato il nuovo ambiente virtuale sarà attivo — potrai vederlo perché l'inizio del prompt sarà il nome dell'environment tra parentesi (sotto mostriamo questo per Ubuntu, ma la linea finale è simile anche per Windows e macOS).</p> + +<pre class="notranslate"><code>$ mkvirtualenv my_django_environment + +Running virtualenv with interpreter /usr/bin/python3 +... +virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/t_env7/bin/get_env_details +(my_django_environment) ubuntu@ubuntu:~$</code> +</pre> + +<p>Ora che sei dentro il virtual environment puoi installare Django e iniziare a sviluppare.</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Da ora in questo articolo (e in effetti nel modulo) considerare che ogni comando venga eseguito in un virtual environment Python come quello che abbiamo settato sopra.</p> +</div> + +<h3 id="Utilizzare_un_Ambiente_Virtuale">Utilizzare un Ambiente Virtuale</h3> + +<p>Ci sono solo pochi altri comandi utili che dovresti conoscere (ce ne sono molti nella documentazione del tool, ma questi sono quelli che userai regolarmente):</p> + +<ul> + <li><code>deactivate</code> — Esci dall'attuale virtual environment Python</li> + <li><code>workon</code> — Elenca i virtual environment disponibili</li> + <li><code>workon name_of_environment</code> — Attiva il virtual environment Python specificato</li> + <li><code>rmvirtualenv name_of_environment</code> — Rimuovi il virtual environment specificato.</li> +</ul> + +<h2 id="Installare_Django">Installare Django</h2> + +<p>Una volta che hai installato <em>Python 3</em> e <em>pip3</em>, e creato un virtual environment, puoi usare <em>pip3</em> per installare Django.</p> + +<pre class="brush: bash notranslate">pip3 install django +</pre> + +<p>Puoi testare se Django è installato eseguendo il seguente comando (questo verifica che Python riesca a trovare il modulo Django):</p> + +<pre class="brush: bash notranslate"># Linux/Mac OS X +python3 -m django --version + 1.10.10 + +# Windows +py -3 -m django --version + 1.10.10 +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Su Windows puoi eseguire script <em>Python 3</em> usando il comando <code>py -3</code>, mentre su Linux/Mac OSX, il comando è <code>python3</code>.</p> +</div> + +<div class="warning"> +<p><strong>Importante</strong>: Il resto di questo <strong>modulo </strong>usa, per invocare Python 3 il comando <em>Linux</em> (<code>python3</code>) . Se stai lavorando su <em>Windows usa</em>: <code>py -3</code></p> +</div> + +<h2 id="Testare_la_tua_installazione">Testare la tua installazione</h2> + +<p>Il test sopra funziona, ma non è molto divertente. Un test più interessante è creare lo scheletro di un progetto e vederlo funzionare. Per farlo, andate tramite linea di comando/terminale dove volete memorizzare le applicazioni Django. Create una cartella per il sito di test ed entrateci.</p> + +<pre class="brush: bash notranslate">mkdir django_test +cd django_test +</pre> + +<p>Ora si può creare lo scheletro di un nuovo sito chiamata "<em>mytestsite</em>" utilizzando il tool <strong>django-admin </strong>come mostrato<strong>.</strong> Dopo la creazione del sito potete esplorare la cartella creata, e troverete lo script principale per la gestione dei progetti, chiamato <strong>manage.py</strong>.</p> + +<pre class="brush: bash notranslate">django-admin startproject mytestsite +cd mytestsite</pre> + +<p>Possiamo avviare il <em>server web di sviluppo</em> dalla cartella usando <strong>manage.py</strong> e il comando <code>runserver</code>.</p> + +<pre class="brush: bash notranslate">$ <strong>python3 manage.py runserver </strong> +Performing system checks... + +System check identified no issues (0 silenced). + +You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. +Run 'python manage.py migrate' to apply them. + +September 19, 2016 - 23:31:14 +Django version 1.10.1, using settings 'mysite.settings' +Starting development server at http://127.0.0.1:8000/ +Quit the server with CONTROL-C. +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Il comando sopra mostra il comando per Linux/macOS. Per ora potete ignorare il messaggio di avviso "13 unapplied migration(s)"!</p> +</div> + +<p>Una volta che il server è in esecuzione potete vedere il sito usando il web browser e andando sul URL: <code>http://127.0.0.1:8000/</code>. Dovreste vedere un sito simile a questo:</p> + +<p><img alt="Django Skeleton App Homepage - Django 2.0" src="https://mdn.mozillademos.org/files/16288/Django_Skeleton_Website_Homepage_2_1.png"></p> + +<ul> +</ul> + +<h2 id="Sommario">Sommario</h2> + +<p>Ora avete un ambiente di sviluppo Django funzionante sul vostro computer.</p> + +<p>Nella sezione di test avete visto brevemente come creare un sito web Django usando <code>django-admin startproject</code>, e come avviarlo sul browser usando il web server di sviluppo (<code><strong>python3 manage.py runserver</strong></code>). Nel prossimo articolo costruiremo una applicazione web semplice, ma completa.</p> + +<h2 id="Vedete_anche">Vedete anche</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/1.10/intro/install/">Guida per l'installazione veloce</a> (documenti Django)</li> + <li><a href="https://docs.djangoproject.com/en/1.10/topics/install/">Come installare Django — Guida completa</a> (documenti Django) - include informazioni su come rimuovere Django</li> + <li><a href="https://docs.djangoproject.com/en/1.10/howto/windows/">Come installare Django su Windows</a> (documenti Django)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}</p> diff --git a/files/it/learn/server-side/django/forms/index.html b/files/it/learn/server-side/django/forms/index.html new file mode 100644 index 0000000000..80c0970f16 --- /dev/null +++ b/files/it/learn/server-side/django/forms/index.html @@ -0,0 +1,678 @@ +--- +title: 'Django Tutorial Part 9: Working with forms' +slug: Learn/Server-side/Django/Forms +translation_of: Learn/Server-side/Django/Forms +--- +<div> {{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django/Testing", "Learn/Server-side/Django")}}</div> + +<p class="summary">In questo tutorial ti mostreremo come lavorare con i form HTML in Django e, in particolare, il modo più semplice per scrivere moduli per creare, aggiornare ed eliminare istanze di modelli. Come parte di questa dimostrazione, estenderemo il sito Web LocalLibrary in modo che i bibliotecari possano rinnovare libri e creare, aggiornare ed eliminare autori utilizzando i nostri moduli (anziché utilizzare l'applicazione di amministrazione).</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td>Completare il precedente tutorial, compreso: <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions">Django Tutorial Part 8: User authentication and permissions</a>.</td> + </tr> + <tr> + <th scope="row">Obiettivi:</th> + <td>Comprendere come scrivere form per ottenere informazioni dagli utenti e aggiornare il database. Per capire come le generiche viste di modifica dei form basate sulla classe possono semplificare enormemente la creazione di form per lavorare con un singolo modello.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica">Panoramica</h2> + +<p>Un <a href="/en-US/docs/Web/Guide/HTML/Forms">HTML Form</a>, o modulo, è un gruppo di uno o più campi/widget su una pagina Web, che può essere utilizzato per raccogliere informazioni dagli utenti per l'invio a un server. I moduli sono un meccanismo flessibile per la raccolta dell'input dell'utente perché ci sono widget adatti per inserire molti tipi diversi di dati, tra cui caselle di testo, caselle di controllo, pulsanti di opzione, selettori di date, ecc. I moduli sono anche un modo relativamente sicuro di condividere i dati con il server, poiché ci consentono di inviare i dati nelle richieste POST con la protezione dalle falsificazioni delle richieste cross-site.</p> + +<p>Anche se finora non abbiamo creato alcun modulo in questo tutorial, li abbiamo già incontrati nel sito di Django Admin. Ad esempio, lo screenshot seguente mostra un modulo per la modifica di uno dei nostri modelli <a href="/en-US/docs/Learn/Server-side/Django/Models">Book</a>, composto da un certo numero di elenchi di selezione e editor di testo.</p> + +<p><img alt="Admin Site - Book Add" src="https://mdn.mozillademos.org/files/13979/admin_book_add.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p> + +<p>Lavorare con i moduli Web può essere complicato! Gli sviluppatori devono scrivere HTML per il modulo, convalidare e bonificare correttamente i dati immessi sul server (e possibilmente anche nel browser), ripubblicare il modulo con messaggi di errore per informare gli utenti di eventuali campi non validi, gestire i dati quando sono stati inviati correttamente e infine rispondere all'utente in qualche modo per indicare il successo. <em>Django Forms</em> prende molto del lavoro da tutti questi passaggi, fornendo un framework che consente di definire i form e i loro campi a livello di codice, e quindi utilizzare questi oggetti per generare il codice HTML del modulo e gestire gran parte della convalida e dell'interazione dell'utente.</p> + +<p>In questo tutorial, ti mostreremo alcuni dei modi in cui puoi creare e lavorare con i moduli e, in particolare, in che modo le viste generiche del modulo di modifica possono ridurre in modo significativo la quantità di lavoro necessario per creare moduli da manipolare i tuoi modelli Lungo la strada, estenderemo la nostra applicazione LocalLibrary aggiungendo un modulo per consentire ai bibliotecari di rinnovare i libri della biblioteca e creeremo pagine per creare, modificare ed eliminare libri e autori (riproducendo una versione di base del modulo mostrato sopra per la modifica libri).</p> + +<h2 id="HTML_Forms">HTML Forms</h2> + +<p>Prima, una breve panoramica degli <a href="/en-US/docs/Learn/HTML/Forms">HTML Forms</a>. Consideriamo un semplice form, con un singolo campo di testo per inserire il nome di alcuni "team" e la relativa etichetta associata:</p> + +<p><img alt="Simple name field example in HTML form" src="https://mdn.mozillademos.org/files/14117/form_example_name_field.png" style="border-style: solid; border-width: 1px; display: block; height: 44px; margin: 0px auto; width: 399px;"></p> + +<p>Un form HTML è definito in un insieme di elementi dentro dei tag <code><form>...</form></code>, contenenti almeno un elemento <code>input</code> di <code>type="submit"</code>.</p> + +<pre class="brush: html"><form action="/team_name_url/" method="post"> + <label for="team_name">Enter name: </label> + <input id="team_name" type="text" name="name_field" value="Default name for team."> + <input type="submit" value="OK"> +</form></pre> + +<p>Mentre qui abbiamo solo un campo di testo per inserire il nome del team, un modulo può avere qualsiasi numero di altri elementi di input e le loro etichette associate. L'attributo <code>type</code> del campo definisce quale tipo di widget verrà visualizzato. Il <code>nome e l'ID</code> del campo vengono utilizzati per identificare il campo in JavaScript / CSS / HTML, mentre il <code>value</code> definisce il valore iniziale per il campo quando viene visualizzato per la prima volta. L'etichetta del team corrispondente viene specificata utilizzando il tag label (vedere "Immettere il nome" sopra), con un campo for che contiene il valore id dell'input associato.</p> + +<p>L'input <code>submit</code> verrà visualizzato come un pulsante (predefinito) che può essere premuto dall'utente per caricare i dati in tutti gli altri elementi di input nel modulo sul server (in questo caso, solo il <code>team_name</code>). Gli attributi del form definiscono il metodo HTTP utilizzato perinviare i dati e la destinazione dei dati sul server (<code>action</code>):</p> + +<ul> + <li><code>action</code>: La risorsa / URL in cui i dati devono essere inviati per l'elaborazione quando viene inviato il modulo. Se questo non è impostato (o impostato su una stringa vuota), il modulo verrà inviato nuovamente all'URL della pagina corrente.</li> + <li><code>method</code>: Il metodo HTTP utilizzato per inviare i dati: post o get. + <ul> + <li>Il metodo POST deve essere sempre utilizzato se i dati determinano una modifica al database del server, in quanto ciò può essere reso più resistente agli attacchi delle richieste di falsificazione intersito.</li> + <li>Il metodo GET deve essere utilizzato solo per form che non modificano i dati dell'utente (ad esempio un form di ricerca). È consigliato quando vuoi essere in grado di aggiungere un segnalibro o condividere l'URL.</li> + </ul> + </li> +</ul> + +<p>Il ruolo del server è innanzitutto quello di rendere lo stato del form iniziale - contenente campi vuoti o prepopolati con valori iniziali. Dopo che l'utente ha premuto il pulsante di invio, il server riceverà i dati del modulo con i valori del browser Web e dovrà convalidare le informazioni. Se il modulo contiene dati non validi, il server dovrebbe visualizzare nuovamente il modulo, questa volta con i dati immessi dall'utente nei campi e nei messaggi "validi" per descrivere il problema per i campi non validi. Una volta che il server riceve una richiesta con tutti i dati del modulo validi, può eseguire un'azione appropriata (ad esempio, salvare i dati, restituire il risultato di una ricerca, caricare un file, ecc.) E quindi avvisare l'utente.</p> + +<p>Come potete immaginare, la creazione dell'HTML, la convalida dei dati restituiti, la ri-visualizzazione dei dati inseriti con i rapporti di errore se necessario e l'esecuzione dell'operazione desiderata su dati validi possono richiedere un notevole sforzo per "avere ragione". Django rende tutto molto più semplice, eliminando parte del pesante codice ripetitivo.</p> + +<h2 id="Processo_di_Django_di_gestione_dei_form">Processo di Django di gestione dei form</h2> + +<p>La gestione dei form di Django utilizza tutte le stesse tecniche apprese in precedenti tutorial (per la visualizzazione di informazioni sui nostri models): la vista riceve una richiesta, esegue tutte le azioni richieste inclusa la lettura dei dati dai modelli, quindi genera e restituisce una pagina HTML ( da un modello, in cui passiamo un contesto contenente i dati da visualizzare). Ciò che rende le cose più complicate è che il server deve anche essere in grado di elaborare i dati forniti dall'utente e visualizzare nuovamente la pagina in caso di errori.</p> + +<p>Di seguito viene mostrato un diagramma di flusso del processo di gestione delle richieste di modulo da parte di Django, a partire da una richiesta per una pagina contenente un form (mostrato in verde).</p> + +<p><img alt="Updated form handling process doc." src="https://mdn.mozillademos.org/files/14205/Form%20Handling%20-%20Standard.png" style="display: block; height: 569px; margin: 0px auto; width: 800px;"></p> + +<p>Basandosi sul diagramma sopra, le cose che principalmente svolge Django nella gestione dei form sono:</p> + +<ol> + <li>Mostra il modulo predefinito la prima volta che viene richiesto dall'utente.</li> +</ol> + +<ul> + <li>Il form può contenere campi vuoti (ad es. Se stai creando un nuovo record), oppure può essere precompilato con valori iniziali (ad es. Se stai cambiando un record o hai valori iniziali predefiniti utili).</li> + <li>A questo punto, il form viene definito come non associato, poiché non è associato a nessun dato inserito dall'utente (sebbene possa avere valori iniziali).</li> +</ul> + +<ol> + <li>Riceve i dati da una richiesta di invio e li associa al modulo. + <ul> + <li>Collegare i dati al modulo significa che i dati inseriti dall'utente e gli eventuali errori sono disponibili quando è necessario visualizzare nuovamente il modulo.</li> + </ul> + </li> + <li>Pulisce e valida i dati. + <ul> + <li>La pulizia dei dati esegue la disinfezione dell'input (ad esempio rimuovendo i caratteri non validi che potrebbero essere utilizzati per inviare contenuto dannoso al server) e li converte in tipi coerenti di Python.</li> + <li>La convalida verifica che i valori siano appropriati per il campo (ad es. Sono nel giusto intervallo di date, non sono troppo corti o troppo lunghi, ecc.)</li> + </ul> + </li> + <li>Se i dati non sono validi, visualizza nuovamente il modulo, questa volta con tutti i valori e i messaggi di errore compilati dall'utente per i campi del problema.</li> + <li>Se tutti i dati sono validi, eseguire le azioni richieste (ad esempio, salvare i dati, inviare e-mail, restituire il risultato di una ricerca, caricare un file, ecc.)</li> + <li>Una volta completate tutte le azioni, reindirizza l'utente a un'altra pagina.</li> +</ol> + +<p>Django fornisce una serie di strumenti e approcci per aiutarti con le attività sopra descritte. La più fondamentale è la classe <code>Form</code>, che semplifica sia la generazione di moduli HTML che la pulizia / convalida dei dati. Nella prossima sezione, descriviamo come le form funzionano usando l'esempio pratico di una pagina per consentire ai bibliotecari di rinnovare i libri.</p> + +<div class="note"> +<p><strong>Note:</strong> Capire come si usa Form ti sarà d'aiuto quando discuteremo le classi di form più "di alto livello" di Django.</p> +</div> + +<h2 id="Modulo_di_rinnovo_del_libro_utilizzando_una_Form_e_funzione_vista">Modulo di rinnovo del libro utilizzando una Form e funzione vista</h2> + +<p>Successivamente, aggiungeremo una pagina per consentire ai bibliotecari di rinnovare i libri presi in prestito. Per fare ciò creeremo un modulo che consenta agli utenti di inserire un valore di data. Daremo il campo con un valore iniziale di 3 settimane rispetto alla data corrente (il normale periodo di prestito) e aggiungiamo alcune convalide per garantire che il bibliotecario non possa inserire una data nel passato o una data troppo lontana nel futuro. Quando è stata inserita una data valida, la scriveremo nel campo BookInstance.due_back del record corrente. L'esempio utilizzerà una vista basata sulle funzioni e una classe Form.</p> + +<p>Le seguenti sezioni spiegano come funzionano le form le modifiche da apportare al nostro progetto LocalLibrary in corso.</p> + +<h3 id="Form">Form</h3> + +<p>La classe Form è il cuore del sistema di gestione delle form di Django. Specifica i campi nel modulo, il loro layout, i widget di visualizzazione, le etichette, i valori iniziali, i valori validi e (una volta convalidati) i messaggi di errore associati ai campi non validi. La classe fornisce anche i metodi per eseguire il rendering stesso nei modelli utilizzando formati predefiniti (tabelle, elenchi, ecc.) O per ottenere il valore di qualsiasi elemento (abilitando il rendering manuale a grana fine).</p> + +<h4 id="Dichiarare_un_Form">Dichiarare un Form</h4> + +<p>La sintassi della dichiarazione per una form è molto simile a quella per la dichiarazione di un modello e condivide gli stessi tipi di campo (e alcuni parametri simili). Questo ha senso perché in entrambi i casi dobbiamo garantire che ogni campo gestisca i giusti tipi di dati, sia vincolato a dati validi e abbia una descrizione per la visualizzazione / documentazione. I dati del modulo sono memorizzati nel file forms.py dell'applicazione, all'interno della directory dell'applicazione. Crea e apri il file locallibrary / catalog / forms.py. Per creare un modulo, importiamo la libreria dei moduli, deriviamo dalla classe Form e dichiariamo i campi del modulo. Di seguito è riportata una classe di modulo molto semplice per il modulo di rinnovo del libro della biblioteca: aggiungi questo al nuovo file:</p> + +<pre class="brush: python">from django import forms + +class RenewBookForm(forms.Form): + renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).") +</pre> + +<h4 id="Form_fields">Form fields</h4> + +<p>In questo caso abbiamo un campo singolo <code><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#datefield">DateField</a></code> per inserire la data di rinnovo che renderizzerà in HTML con un valore vuoto, l'etichetta di default "Data di rinnovo:", e qualche utile testo di utilizzo: "Inserire una data tra ora e 4 settimane (predefinito 3 settimane)." Dato che nessuno degli altri argomenti opzionali è specificato, il campo accetterà le date usando il <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#django.forms.DateField.input_formats">input_formats</a>: YYYY-MM-DD (2016-11-06), MM/DD/YYYY (02/26/2016), MM/DD/YY (10/25/16), e sarà visualizzato con il widget standard <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#widget">widget</a>: <a href="https://docs.djangoproject.com/en/2.1/ref/forms/widgets/#django.forms.DateInput">DateInput</a>.</p> + +<p>Esistono molti altri tipi di campi form, che in gran parte riconoscerete dalla loro somiglianza con le classi di campo del modello equivalente: <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#booleanfield"><code>BooleanField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#charfield"><code>CharField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#choicefield"><code>ChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#typedchoicefield"><code>TypedChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#datefield"><code>DateField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#datetimefield"><code>DateTimeField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#decimalfield"><code>DecimalField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#durationfield"><code>DurationField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#emailfield"><code>EmailField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#filefield"><code>FileField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#filepathfield"><code>FilePathField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#floatfield"><code>FloatField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#imagefield"><code>ImageField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#integerfield"><code>IntegerField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#genericipaddressfield"><code>GenericIPAddressField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#multiplechoicefield"><code>MultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#typedmultiplechoicefield"><code>TypedMultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#nullbooleanfield"><code>NullBooleanField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#regexfield"><code>RegexField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#slugfield"><code>SlugField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#timefield"><code>TimeField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#urlfield"><code>URLField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#uuidfield"><code>UUIDField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#combofield"><code>ComboField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#multivaluefield"><code>MultiValueField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#splitdatetimefield"><code>SplitDateTimeField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#modelmultiplechoicefield"><code>ModelMultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#modelchoicefield"><code>ModelChoiceField</code></a>.</p> + +<p>Gli argomenti comuni alla maggior parte dei campi sono elencati di seguito (questi hanno valori predefiniti sensibili):</p> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#required">required</a>: Se <code>True</code>, il campo non può essere lasciato bianco o <code>None</code>. I campi sono obbligatori per default, quindi se impostiamo <code>required=False</code> autorizzeremo dei campi blank nel form.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#label">label</a>: L'etichetta da utilizzare quando si renderizza la pagina in HTML. Se la <a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#label">label</a> non viene specificata, Django ne creerà uno dal nome del campo capitalizzando la prima lettera e sostituendo gli underscore con gli spazi (ad esempio la data di rinnovo).</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#label-suffix">label_suffix</a>: Di default i due punti vengono visualizzati dopo l'etichetta (ad esempio, data di rinnovo:). Questo argomento consente di specificare un suffisso diverso contenente altri caratteri.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#initial">initial</a>: Il valore iniziale per il campo quando viene visualizzato il modulo.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#widget">widget</a>: Il widget da mostrare.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#help-text">help_text</a> (come visto sopra): testo di aiuto addizionale da mostrare per spiegare l'uso di un campo del form.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#error-messages">error_messages</a>: Una lista di messaggi di errore per il campo. Puoi sovrascrivere tali messaggi coi tuoi se necessario.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#validators">validators</a>: una lista di funzioni da richiamare quando il campo viene validato.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#localize">localize</a>: Abilita la localizzazione nell'input dei dati del form. Vedere il link per maggiori dettagli.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/#disabled">disabled</a>: Il campo viene mostrato ma non è possibile validarlo, se questo attributo è <code>True</code>. Il valore di default è <code>False</code>.</li> +</ul> + +<h4 id="Validazione">Validazione</h4> + +<p>Django offre numerosi posti dove puoi convalidare i tuoi dati. Il modo più semplice per convalidare un singolo campo è sovrascrivere il metodo clean_ <nomecampo> () per il campo che si desidera controllare. Quindi, ad esempio, possiamo effettuare una convalida richiedendo che i valori di renewal_date inseriti siano compresi tra ora e le 4 settimane future implementando clean_renewal_date () come mostrato di seguito.</p> + +<p>Aggiorniamo il file forms.py:</p> + +<pre class="brush: python"><strong>import datetime</strong> + +from django import forms +<strong>from django.core.exceptions import ValidationError +from django.utils.translation import ugettext_lazy as _ +</strong> +class RenewBookForm(forms.Form): + renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).") + +<strong> def clean_renewal_date(self): + data = self.cleaned_data['renewal_date'] + + # Check if a date is not in the past. + if data < datetime.date.today(): + raise ValidationError(_('Invalid date - renewal in past')) + + # Check if a date is in the allowed range (+4 weeks from today). + if data > datetime.date.today() + datetime.timedelta(weeks=4): + raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead')) + + # Remember to always return the cleaned data. + return data</strong></pre> + +<p>Ci sono due cose importanti da notare. Il primo è che otteniamo i nostri dati usando self.cleaned_data ['renewal_date'] e che restituiamo questi dati indipendentemente dal fatto che vengano modificati alla fine della funzione. Questo passaggio ci porta i dati "puliti" e disinfettati da input potenzialmente non sicuri utilizzando i validatori predefiniti e convertiti nel tipo standard corretto per i dati (in questo caso un oggetto datetime.datetime di Python).</p> + +<p>La seconda è che se un valore è al di fuori di quelli ammessi solleviamo un errore di validazione <code>ValidationError</code>, specificando il testo di errore che vogliamo mostrare nel forme se un errore di validazione si è verificato. L'esempio sopra inoltre incapsula il testo in una funzione di traduzione di Django (vedi <a href="https://docs.djangoproject.com/en/2.1/topics/i18n/translation/">Django's translation functions</a>) <code>ugettext_lazy()</code> (importata come <code>_()</code>), che è una good practice in caso tu voglia tradurre il sito successivamente.</p> + +<div class="note"> +<p><strong>Note:</strong> Esistono molti metodi per validare i form, consultare <a href="https://docs.djangoproject.com/en/2.1/ref/forms/validation/">Form and field validation</a> (Django docs). Per esempio, in alcuni casi in cui si hanno diversi campi che dipendono uno dall'altro si può sovrascrivere la funzione <a href="https://docs.djangoproject.com/en/2.1/ref/forms/api/#django.forms.Form.clean">Form.clean()</a> e nuovamente sollevare una <code>ValidationError</code>.</p> +</div> + +<p>Questo è tutto ciò di cui abbiamo bisogno per il form in questo esempio!</p> + +<h3 id="Configurazione_URL">Configurazione URL</h3> + +<p>Prima di creare la nostra vista, aggiungiamo una configurazione URL per la pagina dei rinnovi. Copia la seguente configurazione nella parte inferiore di locallibrary / catalog / urls.py.</p> + +<pre class="brush: python">urlpatterns += [ + path('book/<uuid:pk>/renew/', views.renew_book_librarian, name='renew-book-librarian'), +]</pre> + +<p>La configurazione URL reindirizzerà tutti gli URL con formato <strong>/catalog/book/<em><bookinstance id></em>/renew/</strong> alla funzione <code>renew_book_librarian()</code> in <strong>views.py</strong>, e manderà l'id della <code>BookInstance</code> come parametro con nome <code>pk</code>. Il pattern matcha solamente se <code>pk</code> è un dato <code>uuid</code> correttamente formattato.</p> + +<div class="note"> +<p><strong>Note</strong>: Possiamo nominare qualsiasi cosa ci piaccia dai nostri dati di URL acquisiti anzichè "pk" , perché abbiamo il controllo completo sulla funzione di visualizzazione (non stiamo usando una classe di vista di dettaglio generica che si aspetta parametri con un certo nome). Tuttavia, pk abbreviazione di "chiave primaria", è una convenzione ragionevole da usare!</p> +</div> + +<h3 id="Vista">Vista</h3> + +<p>Come discusso in <a href="#django_form_handling_process">Django form handling process</a>, la vista deve eseguire il rendering del modulo predefinito quando viene chiamato per la prima volta e quindi eseguire nuovamente il rendering con messaggi di errore se i dati non sono validi oppure elaborare i dati e reindirizzare a una nuova pagina se i dati sono validi. Per poter eseguire queste diverse azioni, la vista deve essere in grado di sapere se è stata richiamata per la prima volta per il rendering del modulo predefinito o un tempo successivo per convalidare i dati.</p> + +<p>Per i form che usano una <code>POST</code> per mandare infromazioni al server, il pattern più comune è fare in modo che sia la view ad eseguire i test verso la richiesta di <code>POST</code> (<code>if request.method == 'POST':</code>) identificare le richieste di convalida del modulo e GET (utilizzando un'altra condizione) per identificare la richiesta iniziale di creazione del modulo. Se si desidera inviare i dati utilizzando una richiesta GET, un approccio tipico per identificare se questa è la prima o successiva chiamata alla vista è leggere i dati del modulo (ad esempio, per leggere un valore nascosto nel modulo).</p> + +<p>Il processo di rinnovo del libro verrà scritto nel nostro database, quindi, per convenzione, utilizziamo l'approccio di richiesta POST. Il frammento di codice seguente mostra il modello (molto standard) per questo tipo di visualizzazione delle funzioni.</p> + +<pre class="brush: python">import datetime + +from django.shortcuts import render, get_object_or_404 +from django.http import HttpResponseRedirect +from django.urls import reverse + +from catalog.forms import RenewBookForm + +def renew_book_librarian(request, pk): + book_instance = get_object_or_404(BookInstance, pk=pk) + + # Se è una richiesta di tipo POST allora processa i dati della Form +<strong> if request.method == 'POST':</strong> + + # Crea un'istanza della form e la popola con i dati della richiesta (binding): + form = RenewBookForm(request.POST) + + # Controlla se la form è valida: + <strong>if form.is_valid():</strong> + # process the data in form.cleaned_data as required (here we just write it to the model due_back field) + book_instance.due_back = form.cleaned_data['renewal_date'] + book_instance.save() + + # reindirizza ad un nuovo URL: + return HttpResponseRedirect(reverse('all-borrowed') ) + + # Se la richiesta è GET o un altro metodo crea il form di default +<strong> else:</strong> + proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3) + form = RenewBookForm(initial={'renewal_date': proposed_renewal_date}) + + context = { + 'form': form, + 'book_instance': book_instance, + } + + return render(request, 'catalog/book_renew_librarian.html', context)</pre> + +<p>Innanzitutto, importiamo il nostro form (RenewBookForm) e una serie di altri oggetti / metodi utili utilizzati nel corpo della funzione di visualizzazione:</p> + +<ul> + <li><code><a href="https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/#get-object-or-404">get_object_or_404()</a></code>: Ritorna uno specifico oggetto da un modello basato sulla propria chiave primaria, e solleva un'eccezione <code>Http404</code> (not found) se il record non esiste. </li> + <li><code><a href="https://docs.djangoproject.com/en/2.1/ref/request-response/#django.http.HttpResponseRedirect">HttpResponseRedirect</a></code>: Questo crea un reindirizzamento verso un URL specificato (codice di stato HTTP 302).</li> + <li><code><a href="https://docs.djangoproject.com/en/2.1/ref/urlresolvers/#django.urls.reverse">reverse()</a></code>: Questo genera un URL da un nome di configurazione URL e un set di argomenti. È l'equivalente Python del tag url che abbiamo utilizzato nei nostri templates.</li> + <li><code><a href="https://docs.python.org/3/library/datetime.html">datetime</a></code>: Una libreria Python per manipolare date e ore.</li> +</ul> + +<p>Nella vista, per prima cosa utilizziamo l'argomento pk in get_object_or_404 () per ottenere l'attuale BookInstance (se questo non esiste, la vista verrà immediatamente chiusa e la pagina mostrerà un errore "non trovato"). Se questa non è una richiesta POST (gestita dalla clausola else), creiamo il form predefinito che passa un valore iniziale per il campo renewal_date (come mostrato in grassetto sotto, questo è 3 settimane dalla data corrente). </p> + +<pre class="brush: python"> book_instance = get_object_or_404(BookInstance, pk=pk) + + # Se la richiesta è GET o un altro metodo crea il form di default + else: + proposed_renewal_date = datetime.date.today() + datetime.timedelta(<strong>weeks=3</strong>) + <strong>form = RenewBookForm(initial={'renewal_date': proposed_renewal_date})</strong> + + context = { + 'form': form, + 'book_instance': book_instance, + } + + return render(request, 'catalog/book_renew_librarian.html', context)</pre> + +<p>Dopo aver creato il modulo, chiamiamo render() per creare la pagina HTML, specificando il modello e un contesto che contiene il nostro form. In questo caso, il contesto contiene anche il nostro BookInstance, che utilizzeremo nel modello per fornire informazioni sul libro che stiamo rinnovando.</p> + +<p>Tuttavia, se si tratta di una richiesta POST, allora creiamo il nostro oggetto form e lo popoliamo con i dati della richiesta. Questo processo è chiamato "binding" e ci consente di convalidare il form. Controlliamo quindi se il form è valido, eseguiamo tutto il codice di convalida su tutti i campi, compreso il codice generico per verificare che il nostro campo data sia effettivamente una data valida e la funzione clean_renewal_date() del nostro from specifico per verificare se la data è nella giusta fascia.</p> + +<pre class="brush: python"> # If this is a POST request then process the Form data + if request.method == 'POST': + + # Create a form instance and populate it with data from the request (binding): +<strong> form = RenewBookForm(request.POST)</strong> + + # Check if the form is valid: + if form.is_valid(): + # process the data in form.cleaned_data as required (here we just write it to the model due_back field) + book_instance.due_back = form.cleaned_data['renewal_date'] + book_instance.save() + + # redirect to a new URL: + return HttpResponseRedirect(reverse('all-borrowed') ) + + context = { + 'form': form, + 'book_instance': book_instance, + } + + return render(request, 'catalog/book_renew_librarian.html', context)</pre> + +<p>Se il form non è valido, viene richiamata nuovamente la funzione <code>render()</code>, ma questa volta il form viene passato al contesto con dei messaggi di errore. </p> + +<p>Se il form è valido, allora possiamo iniziare ad utilizzare i dati, accedendovi tramite l'attributo <code>form.cleaned_data</code> (ad es. <code>data = form.cleaned_data['renewal_date']</code>). Qui salviamo semplicemente i dati nel valore due_back dell'oggetto BookInstance associato.</p> + +<div class="warning"> +<p><strong>Importante</strong>: Anche se è possibile accedere ai dati del form direttamente tramite la richiesta, per esempio utilizzando <code>request.POST['renewal_date']</code> o <code>request.GET['renewal_date']</code> se invece stiamo utilizzando una richiesta GET, Ciò NON è raccomandabile. I dati ripuliti, sanificati, e validati, vengono convertiti in tipi adatti a Python.</p> +</div> + +<p>Il passo finale nella manipolazione dei formè la direzione verso un'altra pagina, generalmente una "success" page. In questo caso utilizziamo <code>HttpResponseRedirect</code> e <code>reverse()</code> per ridirezionare alla vista nominata "<code>all-borrowed'</code> (creata come "challenge" in <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions#Challenge_yourself">Django Tutorial Part 8: User authentication and permissions</a>). Se non l'hai creata, ridireziona alla home page con URL '/').</p> + +<p>Questo è tutto ciò che ci serviva per il per la manipolazione dei form, ma dobbiamo ancora restringere gli accessi dei bibliotecari. Probabilmente dovremmo creare un nuovo permesso sull'oggetto <code>BookInstance</code> ("<code>can_renew</code>"), ma, per mantenere le cose più semplici, useremo solo il decoratore di funzione <code>@permission_required</code> con il nostro permesso esistente <code>can_mark_returned.</code></p> + +<p>La vista finale è quindi come di seguito. Copiare questo in fondo a <strong>locallibrary/catalog/views.py</strong>.</p> + +<pre><strong>import datetime + +from django.contrib.auth.decorators import permission_required</strong> +from django.shortcuts import get_object_or_404 +from django.http import HttpResponseRedirect +from django.urls import reverse + +from catalog.forms import RenewBookForm + +<strong>@permission_required('catalog.can_mark_returned')</strong> +def renew_book_librarian(request, pk): + """View function for renewing a specific BookInstance by librarian.""" + book_instance = get_object_or_404(BookInstance, pk=pk) + + # If this is a POST request then process the Form data + if request.method == 'POST': + + # Create a form instance and populate it with data from the request (binding): + form = RenewBookForm(request.POST) + + # Check if the form is valid: + if form.is_valid(): + # process the data in form.cleaned_data as required (here we just write it to the model due_back field) + book_instance.due_back = form.cleaned_data['renewal_date'] + book_instance.save() + + # redirect to a new URL: + return HttpResponseRedirect(reverse('all-borrowed') ) + + # If this is a GET (or any other method) create the default form. + else: + proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3) + form = RenewBookForm(initial={'renewal_date': proposed_renewal_date}) + + context = { + 'form': form, + 'book_instance': book_instance, + } + + return render(request, 'catalog/book_renew_librarian.html', context) +</pre> + +<h3 id="Il_template">Il template</h3> + +<p>Creiamo il template referenziato nella view (<strong>/catalog/templates/catalog/book_renew_librarian.html</strong>) e copiamo il codice sotto:</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <h1>Renew: \{{ book_instance.book.title }}</h1> + <p>Borrower: \{{ book_instance.borrower }}</p> + <p{% if book_instance.is_overdue %} class="text-danger"{% endif %}>Due date: \{{ book_instance.due_back }}</p> + +<strong> <form action="" method="post"> + {% csrf_token %} + <table> + \{{ form.as_table }} + </table> + <input type="submit" value="Submit"> + </form></strong> +{% endblock %}</pre> + +<p>La maggior parte di questo sarà completamente familiare dai tutorial precedenti. Estendiamo il modello di base e quindi ridefiniamo il blocco del contenuto. Siamo in grado di fare riferimento a \{{book_instance}} (e alle sue variabili) perché è stato passato all'oggetto contesto nella funzione render (), e le possiamo usare per elencare il titolo del libro, il mutuatario e la data di scadenza originale.</p> + +<p>Il codice del form è relativamente semplice. Per prima cosa dichiariamo i tag del form, specificando dove deve essere inviato il form (action) e il metodo per inviare i dati (in questo caso un "POST HTTP") - se si richiama la panoramica dei moduli HTML nella parte superiore della pagina, un'azione vuota come mostrato, significa che i dati del modulo saranno postati all'URL attuale della pagina (che è ciò che vogliamo!). All'interno dei tag, definiamo l'input di invio, che un utente può premere per inviare i dati. Il {% csrf_token%} aggiunto appena dentro i tag del modulo fa parte della protezione dalle contraffazioni di Django.</p> + +<div class="note"> +<p><strong>Note:</strong> Aggiungi il {% csrf_token%} a ogni modello Django che crei che utilizza POST per inviare i dati. Ciò ridurrà la possibilità che le form vengano corrotte da utenti malintenzionati</p> +</div> + +<p>Tutto ciò che rimane è la variabile di template \{{form}}, che abbiamo passato al template nel dizionario di contesto. Forse non sorprendentemente, se usato come mostrato, fornisce il rendering predefinito di tutti i campi del modulo, incluse le loro etichette, i widget e il testo della guida: il rendering è come mostrato di seguito:</p> + +<pre class="brush: html"><tr> + <th><label for="id_renewal_date">Renewal date:</label></th> + <td> + <input id="id_renewal_date" name="renewal_date" type="text" value="2016-11-08" required> + <br> + <span class="helptext">Enter date between now and 4 weeks (default 3 weeks).</span> + </td> +</tr> +</pre> + +<div class="note"> +<p><strong>Note:</strong> Forse non è ovvio perché abbiamo solo un campo, ma, per impostazione predefinita, ogni campo è definito nella propria riga della tabella. Questo stesso rendering viene fornito se si fa riferimento alla variabile del template \{{form.as_table}}.</p> +</div> + +<p>Se dovessi inserire una data non valida, avresti anche un elenco degli errori visualizzati nella pagina (mostrati in grassetto sotto).</p> + +<pre class="brush: html"><tr> + <th><label for="id_renewal_date">Renewal date:</label></th> + <td> +<strong> <ul class="errorlist"> + <li>Invalid date - renewal in past</li> + </ul></strong> + <input id="id_renewal_date" name="renewal_date" type="text" value="2015-11-08" required> + <br> + <span class="helptext">Enter date between now and 4 weeks (default 3 weeks).</span> + </td> +</tr></pre> + +<h4 id="Altri_modi_di_usare_le_variabili_template">Altri modi di usare le variabili template</h4> + +<p>Utilizzando<code>\{{ form.as_table }}</code> come mostrato sopra, ogni campo viene renderizzato come riga di una tabella. Puoi anche renderizzare ogni campo come elemento di una lista (usando <code>\{{ form.as_ul }}</code> ) o come un paragrafo (<code>\{{ form.as_p }}</code>).</p> + +<p>È anche possibile avere il controllo completo sul rendering di ogni parte del form, indicizzando le sue proprietà mediante la notazione dei punti. Ad esempio, possiamo accedere a un numero di elementi separati per il nostro campo renewal_date:</p> + +<ul> + <li><code>\{{ form.renewal_date }}:</code> L'intero campo.</li> + <li><code>\{{ form.renewal_date.errors }}</code>: La lista degli errori.</li> + <li><code>\{{ form.renewal_date.id_for_label }}</code>: L'id della label.</li> + <li><code>\{{ form.renewal_date.help_text }}</code>: il testo di aiuto del campo.</li> +</ul> + +<p>Per ulteriori esempi su come eseguire il rendering manuale dei form nei modelli e ciclare dinamicamente sui campi del modello, vedere <a href="https://docs.djangoproject.com/en/2.1/topics/forms/#rendering-fields-manually">Working with forms > Rendering fields manually</a> (Django docs).</p> + +<h3 id="Testare_la_pagina">Testare la pagina</h3> + +<p>Se hai accettato la sfida proposta in <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions#Challenge_yourself">Django Tutorial Part 8: User authentication and permissions</a> dovresti avere una lista di libri in prestito nella libreria, che saranno visibili solamente allo staff. Possiamo aggiungere un link alla nostra pagina di rinnovo per ogni elemento utilizzando il codice template sotto.</p> + +<pre class="brush: html">{% if perms.catalog.can_mark_returned %}- <a href="{% url 'renew-book-librarian' bookinst.id %}">Renew</a> {% endif %}</pre> + +<div class="note"> +<p><strong>Note</strong>: Remember that your test login will need to have the permission "<code>catalog.can_mark_returned</code>" in order to access the renew book page (perhaps use your superuser account).</p> +</div> + +<p>In alternativa, puoi costruire manualmente un URL di prova come questo: http://127.0.0.1:8000/catalog/book/<bookinstance_id>/renew/ (è possibile ottenere un id valido per le librerie navigando a una pagina dei dettagli del libro nella libreria, e copiare il campo id).</p> + +<h3 id="Come_appare">Come appare?</h3> + +<p>Se hai successo, il form di default sarà così:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14209/forms_example_renew_default.png" style="border-style: solid; border-width: 1px; display: block; height: 292px; margin: 0px auto; width: 680px;"></p> + +<p>The form with an invalid value entered will look like this:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14211/forms_example_renew_invalid.png" style="border-style: solid; border-width: 1px; display: block; height: 290px; margin: 0px auto; width: 658px;"></p> + +<p>The list of all books with renew links will look like this:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14207/forms_example_renew_allbooks.png" style="border-style: solid; border-width: 1px; display: block; height: 256px; margin: 0px auto; width: 613px;"></p> + +<h2 id="ModelForms">ModelForms</h2> + +<p>La creazione di una classe Form utilizzando l'approccio descritto sopra è molto flessibile, consente infatti di creare qualsiasi tipo di pagina di form che ti piace e associarla a qualsiasi modello o modello. Tuttavia, se hai solo bisogno di un modulo per mappare i campi di un singolo modello, il tuo modello definirà già la maggior parte delle informazioni necessarie nel tuo modulo: campi, etichette, testo della guida, ecc. Invece di ricreare le definizioni del modello nel tuo forma, è più facile usare la classe helper ModelForm per creare il modulo dal tuo modello. Questo ModelForm può quindi essere utilizzato all'interno delle visualizzazioni esattamente nello stesso modo di un modulo ordinario.</p> + +<p>Un modello di base <code>ModelForm</code> contenente gli stessi campi del nostro <code>RenewBookForm</code> è mostrato sotto. Tutto ciò che devi fare è aggiungere una classe <code>class Meta</code> con il modello associato (<code>BookInstance</code>) e un elenco dei campi del modello da includere nel modulo (è possibile includere tutti i campi utilizzando <code>fields = '__all__',</code> oppure è possibile utilizzare <code>exclude </code>(anziché i campi) per specificare i campi da non includere nel modello).</p> + +<pre class="brush: python">from django.forms import ModelForm + +from catalog.models import BookInstance + +class RenewBookModelForm(ModelForm): +<strong> class Meta: + model = BookInstance + fields = ['due_back']</strong> +</pre> + +<div class="note"> +<p><strong>Note</strong>: Questo potrebbe non sembrare tutto molto più semplice del semplice utilizzo di un modulo (e non è in questo caso, perché abbiamo solo un campo). Tuttavia, se hai molti campi, puoi ridurre la quantità di codice in modo abbastanza significativo!</p> +</div> + +<p>Il resto delle informazioni proviene dalle definizioni del campo del modello (ad esempio etichette, widget, testo della guida, messaggi di errore). Se questi non sono corretti, possiamo sostituirli nella nostra classe Meta, specificando un dizionario contenente il campo da modificare e il suo nuovo valore. Ad esempio, in questo modulo potremmo volere un'etichetta per il nostro campo di "Data di rinnovo" (piuttosto che l'impostazione predefinita in base al nome del campo: "Due Back"), e vogliamo anche che il nostro testo di aiuto sia specifico per questo caso d'uso. La Meta sotto mostra come sovrascrivere questi campi, e puoi impostare allo stesso modo widget e messaggi_errore se i valori predefiniti non sono sufficienti.</p> + +<pre class="brush: python">class Meta: + model = BookInstance + fields = ['due_back'] +<strong> labels = {'due_back': _('New renewal date')} + help_texts = {'due_back</strong><strong>': _('Enter a date between now and 4 weeks (default 3).')} </strong> +</pre> + +<p>Per aggiungere la convalida è possibile utilizzare lo stesso approccio di un modulo normale: si definisce una funzione denominata <code>clean_field_name () </code>e si generano eccezioni <code>ValidationError </code>per valori non validi. L'unica differenza rispetto alla nostra forma originale è che il campo del modello è denominato <code>due_back </code>e non "<code>renewal_date</code>". Questa modifica è necessaria poiché il campo corrispondente in <code>BookInstance </code>è chiamato <code>due_back</code>.</p> + +<pre class="brush: python">from django.forms import ModelForm + +from catalog.models import BookInstance + +class RenewBookModelForm(ModelForm): +<strong> def clean_due_back(self): + data = self.cleaned_data['due_back</strong><strong>'] + + # Controlla se la data non è passata. + if data < datetime.date.today(): + raise ValidationError(_('Invalid date - renewal in past')) + + <strong># Controlla se una data è nell'intervallo consentito (+4 settimane da oggi).</strong> + if data > datetime.date.today() + datetime.timedelta(weeks=4): + raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead')) + + # Ricorda di restituire sempre la data pulita. + return data +</strong> + class Meta: + model = BookInstance + fields = ['due_back'] + labels = {'due_back': _('Renewal date')} + help_texts = {'due_back': _('Enter a date between now and 4 weeks (default 3).')} +</pre> + +<p>La classe <code>RenewBookModelForm</code> <code>adesso funziona come la nostra originale RenewBookForm</code>. Puoi importarla e usarla ovunque attualmente usi <code>RenewBookForm</code> a condizione che si aggiorni anche il nome della variabile corrispondente da <code>renewal_date</code> a <code>due_back</code> come nella dichiarazione della seconda Form: <code>RenewBookModelForm(initial={'due_back': proposed_renewal_date}</code>.</p> + +<h2 id="Generic_editing_views">Generic editing views</h2> + +<p>The form handling algorithm we used in our function view example above represents an extremely common pattern in form editing views. Django abstracts much of this "boilerplate" for you, by creating <a href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-editing/">generic editing views</a> for creating, editing, and deleting views based on models. Not only do these handle the "view" behavior, but they automatically create the form class (a <code>ModelForm</code>) for you from the model.</p> + +<div class="note"> +<p><strong>Note: </strong>In addition to the editing views described here, there is also a <a href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-editing/#formview">FormView</a> class, which lies somewhere between our function view and the other generic views in terms of "flexibility" vs "coding effort". Using <code>FormView</code>, you still need to create your <code>Form</code>, but you don't have to implement all of the standard form-handling patterns. Instead, you just have to provide an implementation of the function that will be called once the submitted is known to be valid.</p> +</div> + +<p>In this section we're going to use generic editing views to create pages to add functionality to create, edit, and delete <code>Author</code> records from our library — effectively providing a basic reimplementation of parts of the Admin site (this could be useful if you need to offer admin functionality in a more flexible way that can be provided by the admin site).</p> + +<h3 id="Views">Views</h3> + +<p>Open the views file (<strong>locallibrary/catalog/views.py</strong>) and append the following code block to the bottom of it:</p> + +<pre class="brush: python">from django.views.generic.edit import CreateView, UpdateView, DeleteView +from django.urls import reverse_lazy + +from catalog.models import Author + +class AuthorCreate(CreateView): + model = Author + fields = '__all__' + initial = {'date_of_death': '05/01/2018'} + +class AuthorUpdate(UpdateView): + model = Author + fields = ['first_name', 'last_name', 'date_of_birth', 'date_of_death'] + +class AuthorDelete(DeleteView): + model = Author + success_url = reverse_lazy('authors')</pre> + +<p>As you can see, to create, update, or delete the views you need to derive from <code>CreateView</code>, <code>UpdateView</code>, and <code>DeleteView</code> (respectively) and then define the associated model.</p> + +<p>For the "create" and "update" cases you also need to specify the fields to display in the form (using the same syntax as for <code>ModelForm</code>). In this case, we show both the syntax to display "all" fields and how you can list them individually. You can also specify initial values for each of the fields using a dictionary of <em>field_name</em>/<em>value</em> pairs (here we arbitrarily set the date of death for demonstration purposes — you might want to remove that!). By default, these views will redirect on success to a page displaying the newly created/edited model item, which in our case will be the author detail view we created in a previous tutorial. You can specify an alternative redirect location by explicitly declaring parameter <code>success_url</code> (as done for the <code>AuthorDelete</code> class).</p> + +<p>The <code>AuthorDelete</code> class doesn't need to display any of the fields, so these don't need to be specified. You do however need to specify the <code>success_url</code>, because there is no obvious default value for Django to use. In this case, we use the <code><a href="https://docs.djangoproject.com/en/2.1/ref/urlresolvers/#reverse-lazy">reverse_lazy()</a></code> function to redirect to our author list after an author has been deleted — <code>reverse_lazy()</code> is a lazily executed version of <code>reverse()</code>, used here because we're providing a URL to a class-based view attribute.</p> + +<h3 id="Templates">Templates</h3> + +<p>The "create" and "update" views use the same template by default, which will be named after your model: <em>model_name</em><strong>_form.html</strong> (you can change the suffix to something other than <strong>_form</strong> using the <code>template_name_suffix</code> field in your view, e.g. <code>template_name_suffix = '_other_suffix'</code>)</p> + +<p>Create the template file <strong>locallibrary/catalog/templates/catalog/author_form.html</strong> and copy in the text below.</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <form action="" method="post"> + {% csrf_token %} + <table> + \{{ form.as_table }} + </table> + <input type="submit" value="Submit"> + </form> +{% endblock %}</pre> + +<p>This is similar to our previous forms and renders the fields using a table. Note also how again we declare the <code>{% csrf_token %}</code> to ensure that our forms are resistant to CSRF attacks.</p> + +<p>The "delete" view expects to find a template named with the format <em>model_name</em><strong>_confirm_delete.html</strong> (again, you can change the suffix using <code>template_name_suffix</code> in your view). Create the template file <strong>locallibrary/catalog/templates/catalog/author_confirm_delete</strong><strong>.html</strong> and copy in the text below.</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + +<h1>Delete Author</h1> + +<p>Are you sure you want to delete the author: \{{ author }}?</p> + +<form action="" method="POST"> + {% csrf_token %} + <input type="submit" value="Yes, delete."> +</form> + +{% endblock %} +</pre> + +<h3 id="URL_configurations">URL configurations</h3> + +<p>Open your URL configuration file (<strong>locallibrary/catalog/urls.py</strong>) and add the following configuration to the bottom of the file:</p> + +<pre class="brush: python">urlpatterns += [ + path('author/create/', views.AuthorCreate.as_view(), name='author_create'), + path('author/<int:pk>/update/', views.AuthorUpdate.as_view(), name='author_update'), + path('author/<int:pk>/delete/', views.AuthorDelete.as_view(), name='author_delete'), +]</pre> + +<p>There is nothing particularly new here! You can see that the views are classes, and must hence be called via <code>.as_view()</code>, and you should be able to recognize the URL patterns in each case. We must use <code>pk</code> as the name for our captured primary key value, as this is the parameter name expected by the view classes.</p> + +<p>The author create, update, and delete pages are now ready to test (we won't bother hooking them into the site sidebar in this case, although you can do so if you wish).</p> + +<div class="note"> +<p><strong>Note</strong>: Observant users will have noticed that we didn't do anything to prevent unauthorized users from accessing the pages! We leave that as an exercise for you (hint: you could use the <code>PermissionRequiredMixin</code> and either create a new permission or reuse our <code>can_mark_returned</code> permission).</p> +</div> + +<h3 id="Testing_the_page">Testing the page</h3> + +<p>First, log in to the site with an account that has whatever permissions you decided are needed to access the author editing pages.</p> + +<p>Then navigate to the author create page: <a href="http://127.0.0.1:8000/catalog/author/create/">http://127.0.0.1:8000/catalog/author/create/</a>, which should look like the screenshot below.</p> + +<p><img alt="Form Example: Create Author" src="https://mdn.mozillademos.org/files/14223/forms_example_create_author.png" style="border-style: solid; border-width: 1px; display: block; height: 184px; margin: 0px auto; width: 645px;"></p> + +<p>Enter values for the fields and then press <strong>Submit</strong> to save the author record. You should now be taken to a detail view for your new author, with a URL of something like <em>http://127.0.0.1:8000/catalog/author/10</em>.</p> + +<p>You can test editing records by appending <em>/update/</em> to the end of the detail view URL (e.g. <em>http://127.0.0.1:8000/catalog/author/10/update/</em>) — we don't show a screenshot, because it looks just like the "create" page!</p> + +<p>Finally, we can delete the page by appending delete to the end of the author detail-view URL (e.g. <em>http://127.0.0.1:8000/catalog/author/10/delete/</em>). Django should display the delete page shown below. Press <strong>Yes, delete.</strong> to remove the record and be taken to the list of all authors.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14221/forms_example_delete_author.png" style="border-style: solid; border-width: 1px; display: block; height: 194px; margin: 0px auto; width: 561px;"></p> + + + +<h2 id="Challenge_yourself">Challenge yourself</h2> + +<p>Create some forms to create, edit, and delete <code>Book</code> records. You can use exactly the same structure as for <code>Authors</code>. If your <strong>book_form.html</strong> template is just a copy-renamed version of the <strong>author_form.html</strong> template, then the new "create book" page will look like the screenshot below:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14225/forms_example_create_book.png" style="border-style: solid; border-width: 1px; display: block; height: 521px; margin: 0px auto; width: 595px;"></p> + +<ul> +</ul> + +<h2 id="Summary">Summary</h2> + +<p>Creating and handling forms can be a complicated process! Django makes it much easier by providing programmatic mechanisms to declare, render, and validate forms. Furthermore, Django provides generic form editing views that can do <em>almost all</em> the work to define pages that can create, edit, and delete records associated with a single model instance.</p> + +<p>There is a lot more that can be done with forms (check out our See also list below), but you should now understand how to add basic forms and form-handling code to your own websites.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/forms/">Working with forms</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/intro/tutorial04/#write-a-simple-form">Writing your first Django app, part 4 > Writing a simple form</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/api/">The Forms API</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/fields/">Form fields</a> (Django docs) </li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/forms/validation/">Form and field validation</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-editing/">Form handling with class-based views</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/forms/modelforms/">Creating forms from models</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-editing/">Generic editing views</a> (Django docs)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django/Testing", "Learn/Server-side/Django")}}</p> + + + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> diff --git a/files/it/learn/server-side/django/generic_views/index.html b/files/it/learn/server-side/django/generic_views/index.html new file mode 100644 index 0000000000..a59f2046f1 --- /dev/null +++ b/files/it/learn/server-side/django/generic_views/index.html @@ -0,0 +1,626 @@ +--- +title: 'Django Tutorial Part 6: Generic list and detail views' +slug: Learn/Server-side/Django/Generic_views +tags: + - Template + - Tutorial + - View + - django + - django view + - imparare + - inizio + - template django + - views + - viste django +translation_of: Learn/Server-side/Django/Generic_views +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/Home_page", "Learn/Server-side/Django/Sessions", "Learn/Server-side/Django")}}</div> + +<p class="summary">Questo tutorial estenderà il nostro sito <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>, aggiungendo pagine di elenco e pagine di dettaglio per libri e autori. Qui apprenderemo le viste generiche basate su classi e mostreremo come possono ridurre la quantità di codice che devi scrivere per casi di uso comune. Passeremo inoltre alla gestione degli URL in maggiore dettaglio, mostrando come eseguire la corrispondenza di base dei pattern.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td>Completare tutti i tutorial precedenti, incluso <a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a>.</td> + </tr> + <tr> + <th scope="row">Obiettivi:</th> + <td>Comprendere dove e come utilizzare viste generiche basate su classi e come estrarre modelli dagli URL e passare le informazioni alle viste.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica">Panoramica</h2> + +<p>In questo tutorial completeremo la prima versione del sito Web LocalLibrary aggiungendo pagine di elenco e dettagli per libri e autori (o per essere più precisi, ti mostreremo come implementare le pagine del libro e ti guideremo nella creazione dellle pagine dell'autore in modo che possa farle tu stesso!)</p> + +<p>Il processo è simile alla creazione della pagina indice, che abbiamo mostrato nel precedente tutorial. Dovremo comunque creare mappe URL, viste e template. La differenza principale è che per le pagine di dettaglio avremo la sfida aggiuntiva di estrarre le informazioni dai pattern nell'URL e passarle alla view. Per queste pagine, mostreremo un tipo di view completamente diverso: view di elenco e view di dettaglio generiche e basate su classi. Queste possono ridurre in modo significativo la quantità di codice necessario per la view, semplificandone la scrittura e la manutenzione.</p> + +<p>La parte finale del tutorial mostrerà come impaginare i dati quando si utilizzano view generiche di elenco basate su classi.</p> + +<h2 id="Pagina_lista_di_libri">Pagina lista di libri</h2> + +<p>Nella pagina dell'elenco dei libri verrà visualizzato un elenco di tutti i record di libri disponibili nella biblioteca, a cui è possibile accedere utilizzando l'URL: <code>catalog/books/</code>. La pagina mostrerà un titolo e un autore per ogni record, con il titolo che è un collegamento ipertestuale alla relativa pagina dei dettagli del libro. La pagina avrà la stessa struttura e la stessa navigazione di tutte le altre pagine del sito e, pertanto, possiamo estendere il template di base (<strong>base_generic.html</strong>).</p> + +<h3 id="URL_mapping">URL mapping</h3> + +<p>Apri <strong>/catalog/urls.py</strong> e copia la riga in grassetto sotto. Come per la pagina index, la funzione <code>path()</code> definisce un pattern da matchare con l' URL (<strong>'books/'</strong>), una funzione di view che verrà richiamata se l' URL matcha (<code>views.BookListView.as_view()</code>), e un nome per questa particolare mappatura.</p> + +<pre class="brush: python">urlpatterns = [ + path('', views.index, name='index'), +<strong> </strong>path<strong>('books/', views.BookListView.as_view(), name='books'),</strong> +]</pre> + +<p>Come discusso nel precedente tutorial, l'URL deve avere già matchato <code>/catalog</code>, quindi la view sarà richiamata per l'URL: <code>/catalog/books/</code>.</p> + +<p>La funzione view ha un formato diverso rispetto a prima - questo perché questa vista verrà effettivamente implementata come una classe. Noi erediteremo da una funzione di visualizzazione generica esistente che già fa la maggior parte di ciò che vogliamo, invece di scriverla noi stessi daccapo.</p> + +<p>Per le view class-based di Django, si accede a una funzione view appropriata chiamando il metodo di classe <code>as_view()</code>. Questo fa tutto il lavoro necessario per creare un'istanza della classe e assicurarsi che i giusti metodi handler vengano chiamati per le richieste HTTP in arrivo.</p> + +<h3 id="Viste_(class-based)">Viste (class-based)</h3> + +<p>Potremmo facilmente scrivere la view dell'elenco dei libri come una funzione regolare (proprio come la nostra precedente vista indice), che interrogherebbe il database cercando tutti i libri e quindi chiamerebbe <code>render()</code> per passare l'elenco a un template specificato. Invece, utilizzeremo una view elenco generica basata su classi (<code>ListView</code>) — una classe che eredita da una vista esistente. Poiché la vista generica implementa già la maggior parte delle funzionalità di cui abbiamo bisogno e segue la best practice di Django, saremo in grado di creare una vista elenco più robusta con meno codice, meno ripetizioni e, in definitiva, meno manutenzione.</p> + +<p>Apri <strong>catalog/views.py</strong>, e copia il seguente codice nel file:</p> + +<pre class="brush: python">from django.views import generic + +class BookListView(generic.ListView): + model = Book</pre> + +<p>Ecco fatto! la list view generica effettuerà una query al database per prendere tutti i record per lo specifico model (<code>Book</code>) poi effettuerà un render tramite il template in <strong>/locallibrary/catalog/templates/catalog/book_list.html</strong> che creeremo sotto. Dentro al template puoi accedere alla lista dei libri con la variabile <code>object_list</code> OR <code>book_list</code> (cioè, genericamente "<code><em>the_model_name</em>_list</code>").</p> + +<div class="note"> +<p><strong>Nota</strong>: Questo percorso scomodo per la posizione del template non è un errore di stampa: le view generiche cercano i template in <code>/<em>application_name</em>/<em>the_model_name</em>_list.html</code> (<code>catalog/book_list.html</code> in questo caso) dentro l'applicazione <code>/<em>application_name</em>/templates/</code> nella directory (<code>/catalog/templates/)</code>.</p> +</div> + +<p>È possibile aggiungere attributi per modificare il comportamento predefinito sopra. Ad esempio, è possibile specificare un altro file template se è necessario disporre di più viste che utilizzano questo stesso model oppure si potrebbe voler utilizzare un dievrso nome di variabile di template se <code>book_list</code> non è intuitivo per il proprio specifico caso d'uso del template. Probabilmente la variante più utile è quella di modificare/filtrare il sottoinsieme di risultati che vengono restituiti, quindi, invece di elencare tutti i libri, potresti elencare i primi 5 libri letti da altri utenti.</p> + +<pre class="brush: python">class BookListView(generic.ListView): + model = Book + context_object_name = 'my_book_list' # your own name for the list as a template variable + queryset = Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war + template_name = 'books/my_arbitrary_template_name_list.html' # Specify your own template name/location</pre> + +<h4 id="Override_dei_metodi_nelle_viste_class-based">Override dei metodi nelle viste class-based</h4> + +<p>Anche se non è necessario farlo qui, puoi anche sovrascrivere alcuni dei metodi di classe.</p> + +<p>Possiamo, per esempio, sovrascrivere <code>get_queryset()</code> per modificare la lista di record restituiti. Questa metodologia è molto più flessibile rispetto all'attributo <code>queryset</code> come abbiamo fatto nel precedente frammento di codice (sebbene in questo caso non ci sia alcun beneficio reale):</p> + +<pre class="brush: python">class BookListView(generic.ListView): + model = Book + + def get_queryset(self): + return Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war +</pre> + +<p>Possiamo anche sovrascrivere <code>get_context_data()</code> per passare altre variabili addizionali di context al template (es. la lista di libri è passata per default). Il frammento sotto mostra come aggiungere una variabile "<code>some_data</code>" al context (sarà quindi disponibile come variabile del template).</p> + +<pre class="brush: python">class BookListView(generic.ListView): + model = Book + + def get_context_data(self, **kwargs): + # Call the base implementation first to get the context + context = super(BookListView, self).get_context_data(**kwargs) + # Create any data and add it to the context + context['some_data'] = 'This is just some data' + return context</pre> + +<p>Quando si esegue questa operazione è importante seguire lo schema usato sopra:</p> + +<ul> + <li>Per prima cosa prendi il contesto esistente dalla nostra superclasse.</li> + <li>Quindi aggiungi le tue nuove informazioni di contesto.</li> + <li>Quindi restituisci il nuovo contesto (aggiornato).</li> +</ul> + +<div class="note"> +<p><strong>Nota</strong>: Leggi <a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-display/">Built-in class-based generic views</a> (Django docs) per vedere molti altri esempi di cosa puoi fare.</p> +</div> + +<h3 id="Creare_List_View_template">Creare List View template</h3> + +<p>Crea il file HTML <strong>/locallibrary/catalog/templates/catalog/book_list.html</strong> e copia il testo sotto. Come discusso sopra, questo è il file predefinito per un template previsto dalla vista elenco generica basata su classi (per un modello denominato <code>Book</code> in un'applicazione denominata <code>catalog</code>)</p> + +<p>I template per le view generiche sono come qualsiasi altro template (anche se ovviamente il contesto/informazioni passate al template possono differire). Come con il nostro template di <em>index</em>, estendiamo il nostro template di base nella prima riga e poi sostituiamo il blocco denominato <code>content</code>.</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <h1>Book List</h1> + <strong>{% if book_list %}</strong> + <ul> + {% for book in book_list %} + <li> + <a href="\{{ book.get_absolute_url }}">\{{ book.title }}</a> (\{{book.author}}) + </li> + {% endfor %} + </ul> + <strong>{% else %}</strong> + <p>There are no books in the library.</p> + <strong>{% endif %} </strong> +{% endblock %}</pre> + +<p>La view passa il contesto (elenco di libri) di default con <code>object_list</code> e <code>book_list</code> come alias; in ogni caso funzionerà.</p> + +<h4 id="Esecuzione_condizionale">Esecuzione condizionale</h4> + +<p>Usiamo i tag template <code><a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#if">if</a></code>, <code>else</code>, ed <code>endif</code> per controllare se la <code>book_list</code> è stata definita e non è vuota. Se <code>book_list</code> è vuota, allora la clausola <code>else</code> mostra un testo alternativo in cui spiega che non sono presenti record da elencare. Se <code>book_list</code> non è vuota, allora iteriamo sulla lista di libri.</p> + +<pre class="brush: html"><strong>{% if book_list %}</strong> + <!-- code here to list the books --> +<strong>{% else %}</strong> + <p>There are no books in the library.</p> +<strong>{% endif %}</strong> +</pre> + +<p>La condizione sopra fa il test su un'unica condizione, ma si possono effettuare ulteriori test e gestire ulteriori casi, per testare condizioni addizionali si può usare ad esempio il tag <code>elif </code>(es. <code>{% elif var2 %}</code>). Per maggiori informazioni sugli operatori condizionali consultare: <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#if">if</a>, <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#ifequal-and-ifnotequal">ifequal/ifnotequal</a>, <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#ifchanged">ifchanged</a> in <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins">Built-in template tags and filters</a> (Django Docs).</p> + +<h4 id="Cicli_for">Cicli for</h4> + +<p>Il template utilizza i tag <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#for">for</a> <code>endfor</code> per ciclare la lista di libri, come sotto. Ogni iterazione popola la variabile di template <code>book</code> con le informazioni per l'elemento corrente della lista.</p> + +<pre class="brush: html">{% for <strong>book</strong> in book_list %} + <li> <!-- code here get information from each <strong>book</strong> item --> </li> +{% endfor %} +</pre> + +<p>Anche se non usato qui, all'interno del loop Django creerà anche altre variabili che puoi usare per tracciare l'iterazione. Ad esempio, è possibile testare la variabile <code>forloop.last</code> per eseguire l'elaborazione condizionale l'ultima volta che viene eseguito il ciclo.</p> + +<h4 id="Accedere_alle_variabili">Accedere alle variabili</h4> + +<p>Il codice all'interno del ciclo crea un item di elenco per ogni libro che mostra sia il titolo (come collegamento alla vista dei dettagli ancora da creare) sia l'autore.</p> + +<pre class="brush: html"><a href="\{{ book.get_absolute_url }}">\{{ book.title }}</a> (\{{book.author}}) +</pre> + +<p>Accediamo ai campi del record del libro associato utilizzando la "notazione dot" (es. <code>book.title</code> e <code>book.author</code>), dove il testo che segue <code>book</code> è il nome del campo (come definito nel model).</p> + +<p>Possiamo anche chiamare delle <em>functions</em> nel model da dentro il nostro template — in questo caso <code>Book.get_absolute_url()</code> per ottenere un URL che è possibile utilizzare per visualizzare il record di dettaglio associato. Questo funziona a condizione che la funzione non abbia argomenti (non c'è modo di passare argomenti!)</p> + +<div class="note"> +<p><strong>Nota</strong>: Dobbiamo stare attenti agli "effetti collaterali" quando chiamiamo le funzioni nei model. Qui visualizziamo solo un URL, ma una funzione può fare praticamente qualsiasi cosa: non vogliamo rischiare di cancellare il nostro database (per esempio) semplicemente mostrando il nostro template!</p> +</div> + +<h4 id="Update_del_template_di_base">Update del template di base</h4> + +<p>Apri il template di base (<strong>/locallibrary/catalog/templates/<em>base_generic.html</em></strong>) ed inserisci <strong>{% url 'books' %} </strong>dentro il link Url per <strong>All books</strong>, come sotto. Questo abiliterà il link in tutte le pagine (possiamo metterlo in pratica con successo ora che abbiamo creato il mapper URL "libri").</p> + +<pre class="brush: python"><li><a href="{% url 'index' %}">Home</a></li> +<strong><li><a href="{% url 'books' %}">All books</a></li></strong> +<li><a href="">All authors</a></li></pre> + +<h3 id="Come_viene_mostrato">Come viene mostrato?</h3> + +<p>Non sarà ancora possibile creare l'elenco dei libri, perché manca ancora una dipendenza: la mappa degli URL per le pagine dei dettagli del libro, necessaria per creare collegamenti ipertestuali a singoli libri. Mostreremo entrambe le viste elenco e dettaglio dopo la prossima sezione.</p> + +<h2 id="Pagina_di_dettaglio_dei_libri">Pagina di dettaglio dei libri</h2> + +<p>La pagina dei dettagli del libro mostrerà le informazioni su un libro specifico, accessibile tramite l'URL <code>catalog/book/<em><id></em></code> (dove <code><em><id></em></code> è la chiave primaria per il libro). Oltre ai campi nel model Book (autore, sommario, ISBN, lingua e genere), elencheremo anche i dettagli delle copie disponibili (<code>BookInstances</code>) compreso lo stato, la data di ritorno prevista, l'edizione e l'id. Ciò consentirà ai nostri lettori non solo di conoscere il libro, ma anche di confermare se/quando è disponibile.</p> + +<h3 id="URL_mapping_2">URL mapping</h3> + +<p>Apri <strong>/catalog/urls.py</strong> e aggiungi l'URL mapper '<strong>book-detail</strong>' mostrato in grassetto qui sotto. Questa funzione <code>path()</code> definisce un pattern, una vista di dettaglio generica basata sulla classe e un nome.</p> + +<pre class="brush: python">urlpatterns = [ + path('', views.index, name='index'), + path('books/', views.BookListView.as_view(), name='books'), +<strong> path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),</strong> +]</pre> + +<p>Per il path dei dettagli del libro, il pattern URL utilizza una sintassi speciale per catturare l'ID specifico del libro che vogliamo vedere. La sintassi è molto semplice: le parentesi angolari definiscono la parte dell'URL da catturare, racchiudendo il nome della variabile che la vista può utilizzare per accedere ai dati acquisiti. Per esempio, <strong><something></strong> , catturerà il pattern marcato, e passerà il valore alla view come variabile con nome "something". Puoi anche far precedere al nome della variabile una <a href="https://docs.djangoproject.com/en/2.1/topics/http/urls/#path-converters">specifica di conversione</a> che definisce il tipo di dato (int, str, slug, uuid, path).</p> + +<p>In questo caso usiamo <code>'<int:pk>'</code><strong> </strong>per acquisire l'id del libro, che deve essere una stringa appositamente formattata e passarla alla vista come parametro chiamato <code>pk</code> (abbreviazione di primary key). Questo è l'ID che viene utilizzato per archiviare il libro in modo univoco nel database, come definito nel Modello Book.</p> + +<div class="note"> +<p><strong>Nota</strong>: Come discusso precedentemente, il nostro URL matchato in realtà è <code>catalog/book/<digits></code> (ma perchè siamo nell'applicazione <strong>catalog</strong> <code>/catalog/</code> è sottinteso).</p> +</div> + +<div class="warning"> +<p><strong>Importante</strong>: La vista di dettaglio generica basata sulla classe prevede di passare un parametro denominato pk. Se stai scrivendo la tua vista funzione puoi usare qualsiasi nome di parametro che ti piace, o addirittura passare le informazioni in un argomento senza nome.</p> +</div> + +<h4 id="Manuale_di_nozioni_avanzate_su_path_matching_ed_espressioni_regolari">Manuale di nozioni avanzate su path matching ed espressioni regolari</h4> + +<div class="note"> +<p><strong>Nota</strong>: Non avrai bisogno di questa sezione per completare il tutorial! Lo forniamo perché conoscere questa opzione rischia di essere utile nel tuo futuro incentrato su Django.</p> +</div> + +<p>Il pattern matching fornito da <code>path()</code> è semplice ed utile per il caso (molto diffuso) in cui vuoi solo catturare ogni stringa od intero. Se è necessario un filtro più raffinato (ad esempio, per filtrare solo le stringhe con un determinato numero di caratteri), è possibile utilizzare il metodo <a href="https://docs.djangoproject.com/en/2.1/ref/urls/#django.urls.re_path">re_path()</a>.</p> + +<p>Questo metodo funziona esattamente come <code>path()</code> eccetto per il fatto che permette di specificare un pattern utilizzando una Regex. Vedi: <a href="https://docs.python.org/3/library/re.html">Regular expression</a>. Per esempio, avremmo potuto specificare il path precedente con:</p> + +<pre class="brush: python"><strong>re_path(r'^book/(?P<pk>\d+)$', views.BookDetailView.as_view(), name='book-detail'),</strong> +</pre> + +<p>Le espressioni regolari sono uno strumento di mappatura dei pattern incredibilmente potente. Sono, francamente, abbastanza non intuitive e spaventose per i principianti. Di seguito è riportato un primer molto breve!</p> + +<p>La prima cosa da sapere è che di solito le espressioni regolari dovrebbero essere dichiarate usando la sintassi "raw string" letterale (cioè, sono incluse come mostrato: <strong>r'<testo della regex>'</strong>).</p> + +<p>Le parti principali della sintassi che devi conoscere per dichiarare i match del pattern sono:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Symbol</th> + <th scope="col">Meaning</th> + </tr> + </thead> + <tbody> + <tr> + <td>^</td> + <td>Matcha l'inizio del testo</td> + </tr> + <tr> + <td>$</td> + <td>Matcha la fine del testo</td> + </tr> + <tr> + <td>\d</td> + <td>Matcha un numero (0, 1, 2, ... 9)</td> + </tr> + <tr> + <td>\w</td> + <td>Matcha una parola word character, es. ogni maiuscola- o minuscola- dell'alfabeto, numero o underscore (_)</td> + </tr> + <tr> + <td>+</td> + <td>Matcha uno o più caratteri precedenti. Ad esempio, per matchare una o più cifre useresti <code>\d+</code>. Per abbinare uno o più caratteri "a", potresti usare <code>a+</code></td> + </tr> + <tr> + <td>*</td> + <td>Abbina zero o più del carattere precedente. Ad esempio, per abbinare niente o una parola che potresti usare <code>\w*</code></td> + </tr> + <tr> + <td>( )</td> + <td>Cattura la parte del pattern all'interno delle parentesi. Tutti i valori acquisiti verranno passati alla vista come parametri senza nome (se vengono catturati più pattern, i parametri associati verranno forniti nell'ordine in cui sono state dichiarate le acquisizioni)</td> + </tr> + <tr> + <td>(?P<<em>name</em>>...)</td> + <td>Cattura il pattern (indicato da ...) come una variabile con nome (in questo caso "name"). I valori catturati sono passati alla view con il nome specificato. La tua view deve dichiarare un argomento con lo stesso nome!</td> + </tr> + <tr> + <td>[ ]</td> + <td>Abbina uno dei caratteri del set. Per esempio, [abc] matcherà con 'a' o 'b' o 'c'. [-\w] restituirà un match con il carattere '-' o con ogni parola.</td> + </tr> + </tbody> +</table> + +<p>La maggioranza degli altri caratteri può essere presa letteralmente!</p> + +<p>Consideriamo alcuni esempi di pattern realistici:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Pattern</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><strong>r'^book/(?P<pk>\d+)$'</strong></td> + <td> + <p>Matcha una stringa che ha <code>book/</code> all'inizio della linea (<strong>^book/</strong>), dopo ha una o più cifre (<code>\d+</code>), e quindi termina (senza caratteri non numerici prima dell'indicatore di fine riga).</p> + + <p>Cattura anche tutte le cifre <strong>(?P<pk>\d+)</strong> e le passa alla vista in un parametro chiamato 'pk'. <strong>I valori catturati vengono sempre passati come una stringa!</strong></p> + + <p>Ad esempio, <code>book/1234</code> invierà una variabile <code>pk = '1234</code>' alla view.</p> + </td> + </tr> + <tr> + <td><strong>r'^book/(\d+)$'</strong></td> + <td>Questo corrisponde agli stessi URL del caso precedente. Le informazioni acquisite verranno inviate come argomento senza nome alla vista.</td> + </tr> + <tr> + <td><strong>r'^book/(?P<stub>[-\w]+)$'</strong></td> + <td> + <p>Matcha una stringa che ha <code>book/</code> all'inizio della linea (<strong>^book/</strong>), quindi ha uno o più caratteri che sono o un carattere '-' o una parola (<strong>[-\w]+</strong>), e si conclude. Cattura anche questo set di caratteri e li passa alla vista in un parametro chiamato 'stub'.</p> + + <p>Questo è uno schema abbastanza tipico per uno "stub". Gli stub sono chiavi primarie basate sull'uso di URL per i dati. È possibile utilizzare uno stub se si desidera che l'URL del libro sia più informativo. Per esempio <code>/catalog/book/the-secret-garden</code> anzichè <code>/catalog/book/33</code>.</p> + </td> + </tr> + </tbody> +</table> + +<p>È possibile acquisire più pattern nello stesso match e quindi codificare molte informazioni diverse in un URL.</p> + +<div class="note"> +<p><strong>Nota</strong>: Come sfida, considera come potresti codificare un URL per elencare tutti i libri pubblicati in un particolare anno, mese, giorno e RE che potrebbero essere utilizzati per abbinarlo.</p> +</div> + +<h4 id="Passare_opzioni_addizionali_nelle_tue_mappe_URL">Passare opzioni addizionali nelle tue mappe URL</h4> + +<p>Una caratteristica che non abbiamo usato qui, ma che potresti trovare di valore, è che puoi dichiarare e passare alla view <a href="https://docs.djangoproject.com/en/2.1/topics/http/urls/#views-extra-options">opzioni aggiuntive</a>. Le opzioni sono dichiarate come dizionario che si passa come terzo argomento non assegnato (senza nome) alla funzione <code>path()</code>. Questo approccio può essere utile se si desidera utilizzare la stessa view per più risorse e passare i dati per configurarne il comportamento in ciascun caso (di seguito forniamo un template diverso in ciascun caso).</p> + +<pre class="brush: python">path('url/', views.my_reused_view, <strong>{'my_template_name': 'some_path'}</strong>, name='aurl'), +path('anotherurl/', views.my_reused_view, <strong>{'my_template_name': 'another_path'}</strong>, name='anotherurl'), +</pre> + +<div class="note"> +<p><strong>Nota:</strong> Entrambe le opzioni extra e i pattern nominati catturati vengono passati alla view come argomenti con nome. Se si utilizza lo stesso nome sia per un pattern catturato che per un'opzione extra, solo il valore del pattern catturato verrà inviato alla vista (il valore specificato nell'opzione aggiuntiva verrà scartato).</p> +</div> + +<h3 id="View_(class-based)">View (class-based)</h3> + +<p>Apri <strong>catalog/views.py</strong>, e copia il seguente codice alla fine del file:</p> + +<pre class="brush: python">class BookDetailView(generic.DetailView): + model = Book</pre> + +<p>Fatto! Tutto ciò che ti serve fare ora è creare un template chiamato <strong>/locallibrary/catalog/templates/catalog/book_detail.html</strong>, e la view passerà al database l'informazione per lo specifico record di tipo <code>Book</code> estratto dall'URL mapper. All'interno del modello è possibile accedere all'elenco di libri con la variabile template denominata <code>object</code> OR <code>book</code> (cioè genericamente "the_model_name").</p> + +<p>Se necessario, è possibile modificare il template utilizzato e il nome dell'oggetto contesto utilizzato per fare riferimento al libro nel template. È inoltre possibile sovrascrivere i metodi per aggiungere ulteriori informazioni al contesto, ad esempio.</p> + +<h4 id="Cosa_succede_se_il_record_non_esiste">Cosa succede se il record non esiste?</h4> + +<p>Se un record richiesto non esiste, la vista generica basata sulla classe genererà un'eccezione Http404 automaticamente: in produzione, verrà automaticamente visualizzata una pagina appropriata "risorsa non trovata", che è possibile personalizzare se lo si desidera. Solo per darti un'idea di come funziona, il frammento di codice seguente mostra come implementare la vista basata su classi come una funzione se non si stesse utilizzando la vista di dettaglio generica basata sulla classe.</p> + +<pre class="brush: python">def book_detail_view(request, primary_key): + try: + book = Book.objects.get(pk=primary_key) + except Book.DoesNotExist: + raise Http404('Book does not exist') + + return render(request, 'catalog/book_detail.html', context={'book': book}) +</pre> + +<p>La vista prima cerca di ottenere il record del libro specifico dal modello. Se questo fallisce, la vista dovrebbe sollevare un'eccezione Http404 per indicare che il libro è "non trovato". Il passo finale è quindi, come al solito, chiamare render () con il nome del modello e i dati del libro nel parametro di contesto (come dizionario).</p> + +<p>In alternativa, possiamo usare la funzione <code>get_object_or_404()</code> come scorciatoia per sollevare un'eccezione <code>Http404</code> se il record non viene trovato.</p> + +<pre class="brush: python">from django.shortcuts import get_object_or_404 + +def book_detail_view(request, primary_key): + book = get_object_or_404(Book, pk=primary_key) + return render(request, 'catalog/book_detail.html', context={'book': book})</pre> + +<h3 id="Creare_il_template_per_la_vista_dettaglio">Creare il template per la vista dettaglio</h3> + +<p>Crea il file HTML <strong>/locallibrary/catalog/templates/catalog/book_detail.html</strong> ed inserisci il seguente contenuto. come discusso precedentmente, questo nome file di default per il template è quello atteso dalla generica class-based <em>detail</em> view (per un modello di nome <code>Book</code> in una applicazione di nome <code>catalog</code>).</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <h1>Title: \{{ book.title }}</h1> + + <p><strong>Author:</strong> <a href="">\{{ book.author }}</a></p> <!-- author detail link not yet defined --> + <p><strong>Summary:</strong> \{{ book.summary }}</p> + <p><strong>ISBN:</strong> \{{ book.isbn }}</p> + <p><strong>Language:</strong> \{{ book.language }}</p> + <p><strong>Genre:</strong> {% for genre in book.genre.all %} \{{ genre }}{% if not forloop.last %}, {% endif %}{% endfor %}</p> + + <div style="margin-left:20px;margin-top:20px"> + <h4>Copies</h4> + + {% for copy in book.bookinstance_set.all %} + <hr> + <p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'm' %}text-danger{% else %}text-warning{% endif %}">\{{ copy.get_status_display }}</p> + {% if copy.status != 'a' %} + <p><strong>Due to be returned:</strong> \{{copy.due_back}}</p> + {% endif %} + <p><strong>Imprint:</strong> \{{copy.imprint}}</p> + <p class="text-muted"><strong>Id:</strong> \{{copy.id}}</p> + {% endfor %} + </div> +{% endblock %}</pre> + +<ul> +</ul> + +<div class="note"> +<p>Il link dell'autore nel template sopra ha un URL vuoto perché non abbiamo ancora creato una pagina dei dettagli dell'autore. Una volta che esisterà, dovresti aggiornare l'URL in questo modo:</p> + +<pre><a href="<strong>{% url 'author-detail' book.author.pk %}</strong>">\{{ book.author }}</a> +</pre> +</div> + +<p>Anche se un po 'più grande, quasi tutto in questo template è stato descritto in precedenza:</p> + +<ul> + <li>Estendiamo il nostro template di base e facciamo l'override del blocco "content".</li> + <li>Utilizziamo l'elaborazione condizionale per determinare se visualizzare o meno il contenuto specifico.</li> + <li>Usiamo i loop per scorrere gli elenchi di oggetti.</li> + <li>Accediamo ai campi di context usando la notazione dot (poiché abbiamo usato la vista generica di dettaglio, il context è denominato <code>book</code>, potremmo anche usare "<code>object</code>")</li> +</ul> + +<p>Prima non abbiamo visto la funzione interessante <code>book.bookinstance_set.all()</code>. Questo metodo viene auto-magicamente creato da Django per restituire un set di record <code>BookInstance</code> associati con un particolare <code>Book</code>.</p> + +<pre class="brush: python">{% for copy in book.bookinstance_set.all %} + <!-- code to iterate across each copy/instance of a book --> +{% endfor %}</pre> + +<p>Questo metodo è necessario perchè hai dichiarato una <code>ForeignKey</code> (uno-a-molti) solamente da una parte della relazione. Poichè non hai fatto nulla per dichiarare la relazione negli altri ("molti") modelli, non ci sono alcun campo da cui prendere il set di record associati. Per superare questo problema, Django costruisce un appropriata funzione di nome "reverse lookup" (ricerca inversa) che puoi usare. Il nome della funzione viene costruito con le lettere minuscole del modello in cui la <code>ForeignKey</code> è stata dichiarata, seguita da <code>_set</code> (ovvero la funzione creata in <code>Book</code> è <code>bookinstance_set()</code>).</p> + +<div class="note"> +<p><strong>Nota</strong>: Qui usiamo <code>all()</code> per ottenere tutti i record (di default). Anche se puoi usare il metodo <code>filter()</code> per ricevere un sottoinsieme di record nel tuo codice, non puoi farlo direttamente nei template perchè non puoi specificare argomenti nelle funzioni.</p> + +<p>Fai attenzione anche a non definire un ordine (sulla tua vista class-based o model), altrimenti vedrai anche degli errori dal server di sviluppo come questo:</p> + +<pre>[29/May/2017 18:37:53] "GET /catalog/books/?page=1 HTTP/1.1" 200 1637 +/foo/local_library/venv/lib/python3.5/site-packages/django/views/generic/list.py:99: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <QuerySet [<Author: Ortiz, David>, <Author: H. McRaven, William>, <Author: Leigh, Melinda>]> + allow_empty_first_page=allow_empty_first_page, **kwargs) +</pre> + +<p>Ciò si verifica perché <a href="https://docs.djangoproject.com/en/2.1/topics/pagination/#paginator-objects">paginator object</a> si aspetta di vedere alcuni ORDER BY eseguiti sul database sottostante. Senza di esso, non può essere sicuro che i record siano restituiti effettivamente nell'ordine corretto! </p> + +<p>In questo tutorial non abbiamo ancora visto <strong>Pagination</strong> (ancora, ma presto), ma poichè non puoi utilizzare <code>sort_by()</code> e passare un parametro, (stessa cosa con <code>filter()</code>) dovrai scegliere tra tre strade:</p> + +<ol> + <li>Aggiungere un <code>ordering</code> dentro una dichiarazione <code>class Meta</code> nel tuo modello.</li> + <li>Aggiungere un attibuto <code>queryset</code> nella tua view custom class-based, specificando un <code>order_by()</code>.</li> + <li>Aggiungere un metodo <code>get_queryset</code> alla tua view custom class-based e specificando un <code>order_by()</code>.</li> +</ol> + +<p>Se decidi di usare una classe Meta per il model Author (probabilmente non così flessibile come personalizzare la vista basata sulla classe, ma abbastanza facile), ti ritroverai con qualcosa di simile a questo</p> + +<pre>class Author(models.Model): + first_name = models.CharField(max_length=100) + last_name = models.CharField(max_length=100) + date_of_birth = models.DateField(null=True, blank=True) + date_of_death = models.DateField('Died', null=True, blank=True) + + def get_absolute_url(self): + return reverse('author-detail', args=[str(self.id)]) + + def __str__(self): + return f'{self.last_name}, {self.first_name}' + +<strong> class Meta: + ordering = ['last_name']</strong></pre> + +<p>Ovviamente, il campo non necessita di essere un <code>last_name</code>: può essere qualunque altro.</p> + +<p>E per ultimo, ma non meno importante, dovresti ordinare un attributo/colonna che abbia effettivamente un indice (unico o meno) sul tuo database per evitare problemi di prestazioni. Ovviamente, questo non sarà necessario qui, con così pochi libri (e utenti!), ma è qualcosa da tenere a mente per i progetti futuri.</p> +</div> + +<h2 id="Come_viene_visualizzato">Come viene visualizzato?</h2> + +<p>A questo punto, avremmo dovuto creare tutto il necessario per visualizzare sia l'elenco dei libri sia le pagine di dettaglio dei libri. Lancia il comando (<code>python3 manage.py runserver</code>) ed apri sul tuo browser <a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a>.</p> + +<div class="warning"> +<p><strong>Warning: </strong>Non fare ancora clic su nessun link di autore o di dettaglio dell'autore: creerai quelli nella sfida!</p> +</div> + +<p>Click su <strong>All books</strong> per vedere la lista di tutti i libri. </p> + +<p><img alt="Book List Page" src="https://mdn.mozillademos.org/files/14049/book_list_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; height: 216px; margin: 0px auto; width: 823px;"></p> + +<p>Quindi fai clic su un link a uno dei tuoi libri. Se tutto è impostato correttamente, dovresti vedere qualcosa come il seguente screenshot.</p> + +<p><img alt="Book Detail Page" src="https://mdn.mozillademos.org/files/14051/book_detail_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; height: 783px; margin: 0px auto; width: 926px;"></p> + +<h2 id="Impaginazione">Impaginazione</h2> + +<p>Se hai appena qualche record, la nostra pagina di elenco dei libri sembrerà a posto. Tuttavia, inserendo decine o centinaia di record la pagina impiegherà più tempo a caricarsi (e avrà troppi contenuti per navigare in modo ragionevole). La soluzione a questo problema è di aggiungere l'impaginazione alle visualizzazioni della lista, riducendo il numero di elementi visualizzati su ciascuna pagina.</p> + +<p>Django ha un eccellente supporto per l'impaginazione built-in. Ancora meglio, questo è incorporato nelle view lista generiche basate su classe, quindi non devi fare molto per abilitarlo!</p> + +<h3 id="Views">Views</h3> + +<p>Apri <strong>catalog/views.py</strong>, ed aggiungi la riga di codice <code>paginate_by</code> mostrata sotto.</p> + +<pre class="brush: python">class BookListView(generic.ListView): + model = Book + <strong>paginate_by = 10</strong></pre> + +<p>Con questa aggiunta, non appena si hanno più di 10 record, la vista inizierà a impaginare i dati che invia al modello. Si accede alle diverse pagine usando i parametri GET - per accedere alla pagina 2 si utilizzerà l'URL: <code>/catalog/books/<strong>?page=2</strong></code>.</p> + +<h3 id="Templates">Templates</h3> + +<p>Ora che i dati sono impaginati, è necessario aggiungere il supporto al template per scorrere il set di risultati. Poiché potremmo volerlo fare in tutte le view elenco, lo faremo in un modo che possa essere aggiunto al template base.</p> + +<p>Apri <strong>/locallibrary/catalog/templates/<em>base_generic.html</em></strong> e copiaci dentro il seguente blocco di paginazione (evidenziato in grassetto qui in basso) sotto il nostro block content. Il codice controlla innanzitutto se l'impaginazione è abilitata nella pagina corrente. In tal caso, aggiunge i collegamenti successivo e precedente se appropriato (e il numero di pagina corrente).</p> + +<pre class="brush: python">{% block content %}{% endblock %} + +<strong>{% block pagination %} + {% if is_paginated %} + <div class="pagination"> + <span class="page-links"> + {% if page_obj.has_previous %} + <a href="\{{ request.path }}?page=\{{ page_obj.previous_page_number }}">previous</a> + {% endif %} + <span class="page-current"> + <p>Page \{{ page_obj.number }} of \{{ page_obj.paginator.num_pages }}.</p> + </span> + {% if page_obj.has_next %} + <a href="\{{ request.path }}?page=\{{ page_obj.next_page_number }}">next</a> + {% endif %} + </span> + </div> + {% endif %} +{% endblock %} </strong></pre> + +<p>Il <code>page_obj</code> è un oggetto <a href="https://docs.djangoproject.com/en/2.1/topics/pagination/#paginator-objects">Paginator</a> che esisterà se la paginazione viene utilizzata nella pagina corrente. Ti permette di ottenere tutte le informazioni sulla pagina corrente, le pagine precedenti, quante pagine ci sono, ecc.</p> + +<p>Usiamo <code>\{{ request.path }}</code> per ottenere l'URL della pagina corrente per la creazione dei collegamenti di paginazione. Questo è utile perché è indipendente dall'oggetto che stiamo impaginando.</p> + +<p>Ecco fatto!</p> + +<h3 id="Come_viene_visualizzato_2">Come viene visualizzato?</h3> + +<p>Lo screenshot qui sotto mostra l'aspetto della paginazione: se non hai inserito più di 10 titoli nel tuo database, puoi testarlo più facilmente abbassando il numero specificato in <code>paginate_by.</code></p> + +<p>I link di impaginazione sono visualizzati in basso, con i link successivo / precedente visualizzati a seconda della pagina in cui ti trovi.</p> + +<p><img alt="Book List Page - paginated" src="https://mdn.mozillademos.org/files/14057/book_list_paginated.png" style="border-style: solid; border-width: 1px; display: block; height: 216px; margin: 0px auto; width: 924px;"></p> + +<h2 id="Sfida_te_stesso">Sfida te stesso</h2> + +<p>La sfida in questo articolo è di creare le view di dettaglio e le view di elenco dell'autore richieste per completare il progetto. Questi dovrebbero essere resi disponibili ai seguenti URL:</p> + +<ul> + <li><code>catalog/authors/</code> — lista di tutti gli authors.</li> + <li><code>catalog/author/<em><id></em></code><em> </em>— Vista di dettaglio dell'autore con chiave primaria <em><code><id></code></em></li> +</ul> + +<p>Il codice richiesto per i mappatori di URL e le viste dovrebbe essere praticamente identico all'elenco di libri e alle viste di dettaglio che abbiamo creato sopra. I modelli saranno diversi ma condivideranno un comportamento simile.</p> + +<div class="note"> +<p><strong>Note</strong>:</p> + +<ul> + <li>Una volta creato il mapper URL per la pagina di elenco dell'autore, sarà necessario aggiornare il collegamento <strong>Tutti gli autori</strong> nel modello di base. Segui lo stesso processo che abbiamo fatto quando abbiamo aggiornato il link <strong>Tutti i libri.</strong></li> + <li>Una volta creato il mapper URL per la pagina dei dettagli dell'autore, è necessario aggiornare anche il <a href="#Creating_the_Detail_View_template">template della vista dettagliata dei libri</a> (<strong>/locallibrary/catalog/templates/catalog/book_detail.html</strong>) in modo che il link dell'autore punti alla nuova pagina dei dettagli dell'autore (anziché essere un URL vuoto). La linea cambierà per aggiungere il tag template mostrato in grassetto sotto. + <pre class="brush: html"><p><strong>Author:</strong> <a href="<strong>{% url 'author-detail' book.author.pk %}</strong>">\{{ book.author }}</a></p> +</pre> + </li> +</ul> +</div> + +<p>Quando hai finito, le tue pagine dovrebbero apparire come gli screenshot qui sotto.</p> + +<p><img alt="Author List Page" src="https://mdn.mozillademos.org/files/14053/author_list_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p> + +<ul> +</ul> + +<p><img alt="Author Detail Page" src="https://mdn.mozillademos.org/files/14055/author_detail_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; height: 358px; margin: 0px auto; width: 825px;"></p> + +<ul> +</ul> + +<h2 id="Sommario">Sommario</h2> + +<p>Congratulazioni, la nostra funzionalità di libreria di base è ora completa!</p> + +<p>In questo articolo, abbiamo imparato come utilizzare la lista generica basata sulla classe e le viste di dettaglio e li abbiamo usati per creare pagine per visualizzare i nostri libri e autori. Lungo la strada abbiamo imparato a conoscere la corrispondenza dei modelli con le espressioni regolari e come puoi passare i dati dagli URL alle tue visualizzazioni. Abbiamo anche imparato qualche altro trucco per l'utilizzo dei modelli. Infine, abbiamo mostrato come impaginare le visualizzazioni degli elenchi in modo che le nostre liste siano gestibili anche quando abbiamo molti record.</p> + +<p>Nei nostri prossimi articoli, estenderemo questa libreria per supportare gli account utente, dimostrando in tal modo l'autenticazione dell'utente, permissons, sessioni e moduli.</p> + +<h2 id="Vedi_anche">Vedi anche</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-display/">Built-in class-based generic views</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-display/">Generic display views</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/intro/">Introduction to class-based views</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins">Built-in template tags and filters</a> (Django docs).</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/pagination/">Pagination</a> (Django docs)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/Home_page", "Learn/Server-side/Django/Sessions", "Learn/Server-side/Django")}}</p> + +<h2 id="In_questo_modulo">In questo modulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> diff --git a/files/it/learn/server-side/django/home_page/index.html b/files/it/learn/server-side/django/home_page/index.html new file mode 100644 index 0000000000..42c8d69eee --- /dev/null +++ b/files/it/learn/server-side/django/home_page/index.html @@ -0,0 +1,419 @@ +--- +title: 'Django Tutorial Parte 5: Creare una Home page' +slug: Learn/Server-side/Django/Home_page +tags: + - Articolo + - Codice + - Script + - Tutorial + - django + - imparare + - lezioni + - server-side + - template django + - viste django +translation_of: Learn/Server-side/Django/Home_page +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}</div> + +<p class="summary">Ora siamo pronti per aggiungere il codice che mostra la nostra prima pagina completa: una home page per il sito web <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>. La home page mostrerà il numero di record che abbiamo per ogni tipo di modello e fornirà i link di navigazione della barra laterale alle nostre altre pagine. Lungo la strada acquisiremo esperienza pratica nella scrittura di mappe e viste URL di base, nel leggere record dal database e utilizzare i templates.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td>Leggere <a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django Introduction</a> e <a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a>.</td> + </tr> + <tr> + <th scope="row">Obiettivi:</th> + <td>Impara a creare semplici mappe url e viste (in cui nessun dato è codificato nell'URL), ottienere dati dai modelli e creare modelli.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica">Panoramica</h2> + +<p>Dopo aver definito i nostri modelli e creato alcuni record della biblioteca iniziale con cui lavorare, è tempo di scrivere il codice che presenta tali informazioni agli utenti. La prima cosa che dobbiamo fare è determinare quali informazioni vogliamo visualizzare nelle nostre pagine e definire gli URL da utilizzare per restituire tali risorse. Quindi creeremo un URL mapper, visualizzazioni e templates per visualizzare le pagine.</p> + +<p>Il diagramma seguente descrive il flusso di dati principale e i componenti richiesti durante la gestione delle richieste e delle risposte HTTP. Siccome abbiamo già implementato il modello, i componenti principali che creeremo sono:</p> + +<ul> + <li>Mapper URL per inoltrare gli URL supportati (e qualsiasi informazione codificata negli URL) alle funzioni di visualizzazione appropriate.</li> + <li>Funzioni view per ottenere i dati richiesti dai model, creare pagine HTML che visualizzano i dati e restituire le pagine all'utente per visualizzarle nel browser.</li> + <li>Template da utilizzare durante il rendering dei dati nelle view.</li> +</ul> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13931/basic-django.png" style="display: block; margin: 0px auto;"></p> + +<p>Come vedrai nella prossima sezione, abbiamo 5 pagine da visualizzare, che sono troppe informazioni da documentare in un singolo articolo. Pertanto, questo articolo si concentrerà su come implementare la home page e tratteremo le altre pagine in un articolo successivo. Questo dovrebbe darti una buona comprensione end-to-end di come funzionano in pratica i mappatori, le viste e i modelli.</p> + +<h2 id="Definizione_degli_URL_delle_risorse">Definizione degli URL delle risorse</h2> + +<p>Siccome questa <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary </a>è essenzialmente di sola lettura per gli utenti finali, abbiamo solo bisogno di fornire una pagina di destinazione per il sito (una home page) e pagine che visualizzano elenchi e viste di dettaglio per libri e autori.</p> + +<p>Gli URL di cui avremo bisogno per le nostre pagine sono:</p> + +<ul> + <li><code>catalog/</code> — La home page.</li> + <li><code>catalog/books/</code> — Lista di libri.</li> + <li><code>catalog/authors/</code> — Lista di tutti gli autori.</li> + <li><code>catalog/book/<em><id></em></code> — Vista di dettaglio per un libro particolare, con una chiave primaria del campo di <id> (di default). Ad esempio, l'URL per il terzo libro aggiunto alla lista sarà <code>/catalog/book/3</code>.</li> + <li><code>catalog/author/<em><id></em></code><em> </em>— Vista di dettaglio per uno specifico autore con un campo primario <em><code><id></code>. </em>Per esempio l'URL per l'11-esimo autore <code>/catalog/author/11</code>.</li> +</ul> + +<p>I primi tre URL restituiranno la pagina di indice, l'elenco di libri e l'elenco di autori. Questi URL non codificano alcuna informazione aggiuntiva e le query che prelevano i dati dal database saranno sempre le stesse. Tuttavia, i risultati restituiti dalle query dipendono dal contenuto del database.</p> + +<p>Al contrario, gli ultimi due URL mostreranno informazioni dettagliate su uno specifico libro o autore. Questi URL codificano l'identità dell'oggetto da visualizzare (rappresentato da <code><em><id></em></code>. Il mapper URL estrarrà le informazioni codificate e le passerà alla view e la view determinerà dinamicamente quali informazioni ottenere dal database. Codificando le informazioni nell'URL useremo un singolo set di una mappatura url, una view e un template per gestire tutti i libri (o gli autori).</p> + +<div class="note"> +<p><strong>Nota</strong>: Con Django, puoi costruire i tuoi URL come richiesto, puoi codificare le informazioni nel corpo dell'URL come mostrato sopra, o includere i parametri <code>GET</code> nell'URL, per esempio <code>/book/?id=6</code>. Qualunque approccio tu usi, gli URL dovrebbero essere mantenuti puliti, logici e leggibili, come <a href="https://www.w3.org/Provider/Style/URI">raccomandato dagli standard W3C</a>.</p> + +<p>La documentazione di Django consiglia di codificare le informazioni nel corpo dell'URL per ottenere una migliore progettazione dell'URL</p> +</div> + +<p>Come accennato nella panoramica, il resto di questo articolo descrive come costruire la pagina indice.</p> + +<h2 id="Creare_la_pagina_index">Creare la pagina index</h2> + +<p>La prima pagina che creeremo è la pagina indice (<code>catalogo/</code>). La pagina indice includerà alcuni HTML statici, insieme ai "conteggi" generati di diversi record nel database. Per fare questo, creeremo una mappatura URL, una view e un template.</p> + +<div class="note"> +<p><strong>Nota</strong>: Vale la pena prestare molta attenzione in questa sezione. La maggior parte delle informazioni si applica anche alle altre pagine che creeremo.</p> +</div> + +<h3 id="Mappatura_dellURL">Mappatura dell'URL</h3> + +<p>Quando abbiamo creato lo <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">scheletro del website</a>, abbiamo aggiornato il file <strong>locallibrary/urls.py</strong> per garantire che ogni volta che un URL che inizia con <code>catalog/</code> viene ricevuto, il modulo <em>URLConf </em>in <code>catalog.urls</code> elaborerà la sottostringa rimanente.</p> + +<p>Il seguente codice da <strong>locallibrary/urls.py </strong>include il modulo <code>catalog.urls</code>:</p> + +<pre>urlpatterns += [ + path('catalog/', include('catalog.urls')), +] +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Ogni volta che Django incontra la funzione di importazione <code>django.urls.include()</code>, divide la stringa URL al carattere finale designato e invia la sottostringa rimanente al modulo URLconf incluso per un'ulteriore elaborazione.</p> +</div> + +<p>Abbiamo anche creato un placeholder file per il modulo <em>URLConf</em>, chiamato <strong>/catalog/urls.py</strong>. Aggiungi il seguente codice a quel file:</p> + +<pre class="brush: python">urlpatterns = [ +<strong> path('', views.index, name='index'),</strong> +]</pre> + +<p>la funzione <code>path()</code>definisce:</p> + +<ul> + <li>Un pattern URL, che è una stringa vuota: ''. Discuteremo i pattern URL in dettaglio quando lavoreremo sulle altre visualizzazioni.</li> + <li>Una funzione di view che verrà chiamata se il pattern URL viene rilevato: <code>views.index</code>, che è la funzione nominata <code>index()</code> nel file <strong>views.py</strong>. </li> +</ul> + +<p>La funzione <code>path()</code> specifica anche un parametro <code>name</code>, che è un identificatore univoco per questa particolare mappatura degli URL. È possibile utilizzare il name per "invertire" il mapper, ovvero creare dinamicamente un URL che punta alla risorsa che il programma di mappatura è progettato per gestire. Ad esempio, possiamo usare il parametro name per collegarci alla nostra home page da qualsiasi altra pagina aggiungendo il seguente link in un template:</p> + +<pre class="brush: html"><a href="<strong>{% url 'index' %}</strong>">Home</a>.</pre> + +<div class="note"> +<p><strong>Nota</strong>: Potremmo anche mettere un link statico <code><a href="<strong>/catalog/</strong>">Home</a></code>), ma se in futuro cambiassimo il pattern della home page, per esempio, in<code>/catalog/index</code>) i templates non si collegheranno più correttamente. L'utilizzo di una mappatura URL invertita è molto più flessibile e robusto.</p> +</div> + +<h3 id="View_function-based">View (function-based)</h3> + +<p>Una vista è una funzione che elabora una richiesta HTTP, recupera i dati richiesti dal database, esegue il rendering dei dati in una pagina HTML utilizzando un template HTML e quindi restituisce l'HTML generato in una risposta HTTP per far visualizzare la pagina all'utente. La vista dell'indice segue questo modello — raccoglie informazioni sul numero di <code>Book</code>, <code>BookInstance</code>, <code>BookInstance</code> disponibili, e <code>Author</code> presenti nel database, e passa tali informazioni a un template per la visualizzazione.</p> + +<p>Apri <strong>catalog/views.py</strong> e nota che il file già importa la funzione di shortcut <a href="https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/#django.shortcuts.render">render()</a> per generare un file HTML usando un template e i dati: </p> + +<pre class="brush: python">from django.shortcuts import render + +# Create your views here. +</pre> + +<p>Incolla le seguenti righe nella parte inferiore del file:</p> + +<pre class="brush: python">from catalog.models import Book, Author, BookInstance, Genre + +def index(request): + """View function for home page of site.""" + + # Generate counts of some of the main objects + num_books = Book.objects.all().count() + num_instances = BookInstance.objects.all().count() + + # Available books (status = 'a') + num_instances_available = BookInstance.objects.filter(status__exact='a').count() + + # The 'all()' is implied by default. + num_authors = Author.objects.count() + + context = { + 'num_books': num_books, + 'num_instances': num_instances, + 'num_instances_available': num_instances_available, + 'num_authors': num_authors, + } + + # Render the HTML template index.html with the data in the context variable + return render(request, 'index.html', context=context)</pre> + +<p>La prima riga importa le classi di modello che useremo per accedere ai dati in tutte le nostre views.</p> + +<p>La prima parte della funzione view recupera il numero di record usando l'attributo <code>objects.all()</code> sulle classi del model. Inoltre prende una lista di oggetti <code>BookInstance</code> che hanno il valore 'a' (Available) nel campo status. Trovi ulteriori informazioni sull'accesso ai dati di modello nel precedente tutorial <a href="/en-US/docs/Learn/Server-side/Django/Models#Searching_for_records">Django Tutorial Part 3: Using models > Searching for records</a>.</p> + +<p>Alla fine della funzione view, chiamiamo la funzione <code>render()</code> per creare una pagina HTML e restituire la pagina come risposta. Questa funzione scorciatoia include una serie di altre funzioni per semplificare un caso d'uso molto comune. La funzione <code>render()</code><strong> </strong>accetta i seguenti parametri:</p> + +<ul> + <li>L'oggetto <code>request</code> originale, che è una <code>HttpRequest</code>.</li> + <li>Un template HTML con dei placeholders per i dati.</li> + <li>Una variabile <code>context</code> (un dizionario Python), che contiene i dati da inserire nei segnaposto.</li> +</ul> + +<p>Approfondiremo <code>context</code> e templates nella prossima sezione. Iniziamo a creare il nostro modello in modo che possiamo effettivamente mostrare qualcosa all'utente!</p> + +<h3 id="Template">Template</h3> + +<p>Un template è un file di testo che definisce la struttura o il layout di un file (come una pagina HTML), utilizzando placeholder per rappresentare contenuto effettivo.</p> + +<p>Django cercherà automaticamente i template in una directory chiamata '<strong>templates</strong>' nella tua applicazione. Ad esempio, nella view index che abbiamo appena aggiunto, la funzione <code>render()</code> si aspetterà di trovare il file <em><strong>index.html</strong> </em>in<em> </em><strong>/locallibrary/catalog/templates/</strong> e solleverà un errore se il file non è presente. Puoi eseguire un controlo salvando i cambiamenti precedenti ed accedendo a <code>127.0.0.1:8000</code> col tuo browser - verrà mostrato un messaggio di errore abbastanza intuitivo: "<code>TemplateDoesNotExist at /catalog/</code>", ed altri dettagli.</p> + +<div class="note"> +<p><strong>Nota</strong>: Sulla base del file delle impostazioni del progetto, Django cercherà i template in un numero di punti, cercando di default nelle applicazioni installate. Puoi trovare ulteriori informazioni su come Django trova i template e su quali formati di modello supporta sulla<a href="https://docs.djangoproject.com/en/2.1/topics/templates/"> sezione Templates della documentazione Django</a>.</p> +</div> + +<h4 id="Estendere_i_templates">Estendere i templates</h4> + +<p>Il template dell'index richiederà un markup HTML standard per la head e il body, insieme alle sezioni di navigazione per collegarsi alle altre pagine del sito che non abbiamo ancora creato e alle sezioni che visualizzano il testo introduttivo e i dati del libro.</p> + +<p>Gran parte della struttura HTML e di navigazione sarà la stessa in ogni pagina del nostro sito. Invece di duplicare il codice su ogni pagina, puoi usare il linguaggio di template di Django per dichiarare un template di base, e quindi estenderlo per sostituire solo i bit che sono diversi per ogni pagina specifica.</p> + +<p>Il seguente frammento di codice è un modello di base di esempio da un file base_generic.html. L'esempio include HTML comune con sezioni per un titolo, una barra laterale e il contenuto principale contrassegnati con i tag di template chiamati <code>block</code> e <code>endblock</code>, mostrati in grassetto. È possibile lasciare i blocchi vuoti o includere il contenuto predefinito da utilizzare durante il rendering delle pagine derivate dal template.</p> + +<div class="note"> +<p><strong>Nota</strong>: I tag Template sono funzioni che è possibile utilizzare in un Template per scorrere gli elenchi, eseguire operazioni condizionali in base al valore di una variabile e così via. Oltre ai tag del template, la sintassi del template consente di fare riferimento alle variabili passate nel template dalla view e utilizzare i <em>template filter</em> per formattare le variabili (ad esempio, per convertire una stringa in lettere minuscole).</p> +</div> + +<pre class="brush: html"><!DOCTYPE html> +<html lang="en"> +<head> + <strong>{% block title %}</strong><title>Local Library</title><strong>{% endblock %}</strong> +</head> +<body> + <strong>{% block sidebar %}</strong><!-- insert default navigation text for every page --><strong>{% endblock %}</strong> + <strong>{% block content %}</strong><!-- default content text (typically empty) --><strong>{% endblock %}</strong> +</body> +</html> +</pre> + +<p>Quando definiamo un template per una particolare vista, per prima cosa specifichiamo il template di base usando il tag <code>extends</code> — vedere il codice di esempio sotto. Quindi dichiariamo quali sezioni del template vogliamo sostituire (se ce ne sono), usando le sezioni <code>block</code>/<code>endblock</code> come nel template di base. </p> + +<p>Ad esempio, il frammento di codice qui sotto mostra come usare il template tag <code>extends</code> ed effettuare un override del block <code>content</code>. L'HTML generato includerà il codice e la struttura definiti nel template di base, incluso il contenuto di default che hai definito nel blocco <code>title</code>, ma il nuovo blocco <code>content</code> al posto di quello di default.</p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <h1>Local Library Home</h1> + <p>Welcome to LocalLibrary, a website developed by <em>Mozilla Developer Network</em>!</p> +{% endblock %}</pre> + +<h4 id="Template_di_base_di_LocalLibrary">Template di base di LocalLibrary</h4> + +<p>Utilizzeremo il seguente snippet di codice come modello di base per il sito Web di LocalLibrary. Come puoi vedere, contiene del codice HTML e definisce i blocchi per <code>title</code>, <code>sidebar</code> e <code>content</code>. Abbiamo un titolo di default e una barra laterale predefinita con collegamenti agli elenchi di tutti i libri e gli autori, entrambi racchiusi in blocchi per essere facilmente modificati in futuro.</p> + +<div class="note"> +<p><strong>Nota</strong>: Presentiamo anche due ulteriori tag di template: <code>url</code> e <code>load static</code>. Questi tag verranno spiegati nelle seguenti sezioni.</p> +</div> + +<p>Crea un nuovo file <strong><em>base_generic.html </em></strong>in <strong>/locallibrary/catalog/templates/</strong> e copia il codice sotto nel file:</p> + +<pre class="brush: html"><!DOCTYPE html> +<html lang="en"> +<head> + {% block title %}<title>Local Library</title>{% endblock %} + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> + <!-- Add additional CSS in static file --> + {% load static %} + <link rel="stylesheet" href="{% static 'css/styles.css' %}"> +</head> +<body> + <div class="container-fluid"> + <div class="row"> + <div class="col-sm-2"> + {% block sidebar %} + <ul class="sidebar-nav"> + <li><a href="{% url 'index' %}">Home</a></li> + <li><a href="">All books</a></li> + <li><a href="">All authors</a></li> + </ul> + {% endblock %} + </div> + <div class="col-sm-10 ">{% block content %}{% endblock %}</div> + </div> + </div> +</body> +</html></pre> + +<p>Il template include CSS da <a href="http://getbootstrap.com/">Bootstrap</a> per migliorare il layout e la presentazione della pagina HTML. Usare di Bootstrap (o di un altro framework web sul lato client) è un modo rapido per creare una pagina attraente che si mostra bene su diverse dimensioni dello schermo.</p> + +<p>Il template di base fa anche riferimento a un file css locale (<strong>styles.css</strong>) che fornisce uno styling aggiuntivo. Crea un file <strong>styles.css</strong> in <strong>/locallibrary/catalog/static/css/</strong> e incolla il seguente codice nel file:</p> + +<pre class="brush: css">.sidebar-nav { + margin-top: 20px; + padding: 0; + list-style: none; +}</pre> + +<h4 id="Il_template_di_index">Il template di index</h4> + +<p>Crea un nuovo file HTML <strong><em>index.html </em></strong>in <strong>/locallibrary/catalog/templates/</strong> and paste the following code in the file. Questo codice estende il nostro template di base sulla prima riga, quindi sostituisce il blocco di <code>content</code> predefinito per il modello. </p> + +<pre class="brush: html">{% extends "base_generic.html" %} + +{% block content %} + <h1>Local Library Home</h1> + <p>Welcome to LocalLibrary, a website developed by <em>Mozilla Developer Network</em>!</p> + <h2>Dynamic content</h2> + <p>The library has the following record counts:</p> + <ul> + <li><strong>Books:</strong> <strong>\{{ num_books }}</strong></li> + <li><strong>Copies:</strong> <strong>\{{ num_instances }}</strong></li> + <li><strong>Copies available:</strong> <strong>\{{ num_instances_available }}</strong></li> + <li><strong>Authors:</strong> <strong>\{{ num_authors }}</strong></li> + </ul> +{% endblock %}</pre> + +<p>Nella sezione <em>Dynamic content </em>dichiariamo i placeholders (<em>variabili del template</em>) per le informazioni dalla view che vogliamo includere. Le variabili sono racchiuse tra doppie parentesi graffe (handlebars), come mostrato in grassetto nel codice di esempio. </p> + +<div class="note"> +<p><strong>Nota:</strong> È possibile riconoscere facilmente variabili di template e tag di template (funzioni) - le variabili sono racchiuse tra doppie parentesi (<code>\{{ num_books }}</code>), e i tag sono racchiusi tra parentesi graffe singole con segni di percentuale (<code>{% extends "base_generic.html" %}</code>).</p> +</div> + +<p>La cosa importante da notare qui è che le variabili sono nominate con le <em>keys</em> che passiamo nel dizionario <code>context</code> nella funzione <code>render()</code> della nostra view (vedi esempio sotto). Le variabili saranno sostituite con i loro valori associati quando il modello è renderizzato. </p> + +<pre class="brush: python">context = { + '<strong>num_books</strong>': num_books, + '<strong>num_instances</strong>': num_instances, + '<strong>num_instances_available</strong>': num_instances_available, + '<strong>num_authors</strong>': num_authors, +} + +return render(request, 'index.html', context=context)</pre> + +<h4 id="Referenziare_file_statici_nei_templates">Referenziare file statici nei templates</h4> + +<p>È probabile che il tuo progetto utilizzi risorse statiche, inclusi JavaScript, CSS e immagini. Perché la posizione di questi file potrebbe non essere nota (o potrebbe cambiare) Django ti consente di specificare la posizione nei tuoi template rispetto alle impostazioni globali di <code>STATIC_URL</code>. Lo scheletro del website imposta il valore di <code>STATIC_URL</code> predefinito a '<code>/static/</code>', ma potresti scegliere di ospitarli su una rete di distribuzione dei contenuti o altrove.</p> + +<p>All'interno del template chiami prima il tag di template <code>load</code> che specifica "statico" per aggiungere la libreria modello, come mostrato nell'esempio di codice seguente. È quindi possibile utilizzare il tag del template <code>static</code> e specificare l'URL relativo al file richiesto.</p> + +<pre class="brush: html"><!-- Add additional CSS in static file --> +{% load static %} +<link rel="stylesheet" href="{% static 'css/styles.css' %}"></pre> + +<p>Puoi anche aggiungere una immagine allo stesso modo, per esempio:</p> + +<pre class="brush: html">{% load static %} +<img src="{% static 'catalog/images/local_library_model_uml.png' %}" alt="UML diagram" style="width:555px;height:540px;"> +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Gli esempi sopra specificano dove si trovano i file, ma Django non li serve di default. Abbiamo configurato il web server di sviluppo per servire i file modificando il mapper URL globale (<strong>/locallibrary/locallibrary/urls.py</strong>) quando <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">abbiamo creato lo scheletro del website</a>, ma è comunque necessario abilitare il file serving in produzione. Lo vedremo più tardi.</p> +</div> + +<p>Per maggiori informazioni sul lavoro con file statici vedere <a href="https://docs.djangoproject.com/en/2.1/howto/static-files/">utilizzare static files</a>.</p> + +<h4 id="Collegarsi_agli_URLs">Collegarsi agli URLs</h4> + +<p>Il template di base sottostante presenta il tag di template URL.</p> + +<pre class="brush: python"><li><a href="{% url 'index' %}">Home</a></li> +</pre> + +<p>Questo tag accetta il nome di una funzione <code>path()</code> chiamata in <strong>urls.py</strong> e i valori per qualsiasi argomento che la vista associata riceverà da quella funzione e restituisce un URL che è possibile utilizzare per collegarsi alla risorsa.</p> + +<h4 id="Configurare_dove_trovare_i_templates">Configurare dove trovare i templates</h4> + +<p>Devi indicare a Django dove cercare i tuoi template nella cartella dei template. Per fare ciò, aggiungi la directory templates all'oggetto TEMPLATES modificando il file <strong>settings.py</strong> come mostrato in grassetto nel seguente esempio di codice:</p> + +<pre class="brush: python">TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ +<strong> os.path.join(BASE_DIR, 'templates'), +</strong> ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +]</pre> + +<h2 id="Come_viene_renderizzato">Come viene renderizzato?</h2> + +<p>A questo punto abbiamo creato tutte le risorse necessarie per visualizzare la pagina indice. Esegui il serve (<code>python3 manage.py runserver</code>) e apri <a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a> nel browser. Se tutto è configurato correttamente, il tuo sito dovrebbe apparire come il seguente screenshot.</p> + +<p><img alt="Index page for LocalLibrary website" src="https://mdn.mozillademos.org/files/14045/index_page_ok.png" style="border-style: solid; border-width: 1px; display: block; height: 356px; margin: 0px auto; width: 874px;"></p> + +<div class="note"> +<p><strong>Nota:</strong> I link <strong>All books</strong> e <strong>All authors</strong> non funzioneranno ancora perché i path, le view e i template per tali pagine non sono definiti. Abbiamo solo inserito i segnaposto per quei link nel template <code>base_generic.html</code>.</p> +</div> + +<h2 id="Prova_tu">Prova tu</h2> + +<p>Ecco un paio di attività per testare la tua familiarità con le query al model, le view e i template.</p> + +<ol> + <li>Il <a href="#The_LocalLibrary_base_template">base template</a> di LocalLibrary include un blocco <code>title</code>. Effettua un override nell' <a href="#The_index_template">index template</a> e crea un nuovo titolo per la pagina. + + <div class="note"> + <p><strong>Consiglio:</strong> La sezione<a href="#Extending_templates"> Extending templates</a> mostra come creare blocchi ed estendere blocchi in altri template.</p> + </div> + </li> + <li>Modifica la <a href="#View_(function-based)">view</a> per generare conteggi per i <em>genres</em> e <em>books</em> che contengono una parola particolare (maiuscole e minuscole) e passano i risultati a <code>context.</code> Lo realizzi in un modo simile alla creazione e all'utilizzo di <code>num_books</code> e <code>num_instances_available</code>. Dopo fai un update dell' <a href="#The_index_template">index template</a> per includere le variabili.</li> +</ol> + +<ul> +</ul> + +<h2 id="Sommario">Sommario</h2> + +<p>Abbiamo appena creato la home page del nostro sito: una pagina HTML che visualizza un numero di record dal database e collegamenti ad altre pagine ancora da creare. Lungo il percorso abbiamo appreso informazioni fondamentali sui mappatori url, le viste, l'interrogazione del database con i modelli, il passaggio di informazioni a un modello da una vista e la creazione e l'estensione di modelli. Nel prossimo articolo svilupperemo questa conoscenza per creare le restanti quattro pagine del nostro sito web.</p> + +<h2 id="Vedi_anche">Vedi anche</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/intro/tutorial03/">Writing your first Django app, part 3: Views and Templates</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/http/urls/">URL dispatcher</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/http/views/">View functions</a> (DJango docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/templates/">Templates</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/howto/static-files/">Managing static files</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/#django.shortcuts.render">Django shortcut functions</a> (Django docs)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}</p> + +<h2 id="In_questo_modulo">In questo modulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> diff --git a/files/it/learn/server-side/django/index.html b/files/it/learn/server-side/django/index.html new file mode 100644 index 0000000000..63e9b5ec39 --- /dev/null +++ b/files/it/learn/server-side/django/index.html @@ -0,0 +1,70 @@ +--- +title: Django Web Framework (Python) +slug: Learn/Server-side/Django +tags: + - CodingScripting + - Intro + - Learn + - Principiante + - Python + - Server-side programming + - TopicStub + - django +translation_of: Learn/Server-side/Django +--- +<div>{{LearnSidebar}}<br> +Django è un server-side web framework Python estremamente popolare. Il modulo mostra perché Django è uno dei server web framework più usati, come impostare l'ambiente di sviluppo e come iniziare ad usarlo per creare le tue web application.</div> + +<div></div> + +<h2 id="Prerequisiti">Prerequisiti</h2> + +<p>Per iniziare non hai bisogno di nessuna conoscenza di Django. Hai bisogno di capire cosa sono la programmazione web lato server e i framework web, leggendo il modulo <a href="/en-US/docs/Learn/Server-side/First_steps">Server-side website programming first steps</a>.</p> + +<p>E' raccomandata una conoscenza generale dei concetti di programmazione e di <a href="/en-US/docs/Glossary/Python">Python</a>, ma non è essenziale per capire i concetti fondamentali.</p> + +<div class="note"> +<p><strong>Nota</strong>: Python è uno dei linguaggi di programmazione più semplici da leggere e capire per i principianti. Detto questo, se vuoi capire meglio questo modulo su Internet puoi trovare numerosi libri gratuiti e tutorial ( nuovi programmatori potrebbero voler leggere la pagina <a href="https://wiki.python.org/moin/BeginnersGuide/NonProgrammers">Python for Non Programmers</a> su python.org wiki).</p> +</div> + +<h2 id="Guide">Guide</h2> + +<dl> + <dt><a href="/it/docs/Learn/Server-side/Django/Introduction">Introduzione a Django</a></dt> + <dd>In questo primo articolo su Django risponderemo alla domanda "Cosa è Django?" e daremo una panoramica su cosa rende questo framework web speciale. Sottolineeremo le caratteristiche principali, inclusa qualche funzionalità avanzata di cui non abbiamo il tempo per parlarne in dettaglio in questo modulo. Mostreremo anche alcuni blocchi principali che compongono una applicazione Django, questo per dare una idea di cosa può fare prima ancora che tu possa configurarlo e iniziare a giocarci.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/development_environment"> Configurare un ambiente di sviluppo per Django</a></dt> + <dd>Ora che sai cosa è Django, mostreremo come configurare e testare un ambiente di sviluppo di Django su Windows, Linux (Ubuntu), e Mac OS X — o qualunque sistema operativo comune tu stia usando, questo articolo ti darà quello che ti server per iniziare lo sviluppo di applicazioni Django.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: Il sito "Local Library"</a></dt> + <dd>Primo articolo nella serie di tutorial pratici che spiega cosa imparerai, e fornirà una panoramica del sito web, di esempio, "local library" su cui lavoreremo e che evolverà nei seguenti articoli.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Parte 2: Creare lo scheletro di un sito web</a></dt> + <dd>Questo articolo mostra come puoi creare lo scheletro del progetto che potrai continuare a popolare con impostazioni specifiche, url, modelli, view e template.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/Models">Django Tutorial Parte 3: Usare i modelli</a></dt> + <dd>Questo articolo mostra come definire i modelli per il sito <em>LocalLibrary</em> — i modelli rappresentano le strutture dati usate per memorizzare i dati dell'applicazione, e permette a Django di salvare i dati in un database. Spiega cosa è un modello, come si dichiara e alcuni dei tipi di dati principali. Inoltre mostra brevemente alcuni dei modi principali con cui accedere il modello dei dati.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Parte 4: Django admin site</a></dt> + <dd>Ora che abbiamo creato i modelli per il LocalLibrary website, useremo il sito Django Admin per aggiungere qualche "real" book data. Prima ti mostreremo come registrare i modelli con il sito admin, quindi ti mostreremo come effettuare il login e creare qualche dato. Infine mostriamo qualcuno dei modi con cui puoi migliorare la presentazione del sito admin.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/Home_page">Django Tutorial Parte 5: Creare la nostra home page</a></dt> + <dd>Ora siamo pronti ad aggiungere il codice per visualizzare la nostra prima pagina intera, una home page per il sito <em>LocalLibrary</em> che mostra quanti record abbiamo di ogni tipo di modello e fornisce collegamenti di navigazione della barra laterale alle altre nostre pagine. Lungo la strada acquisiremo esperienza pratica nella scrittura di URL maps e views, ottenendo dei record dal database e usando i templates.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Parte 6: Generic list and detail views</a></dt> + <dd>Questo tutorial estende il nostro sito <em>LocalLibrary</em>, aggiungendo pagine con liste e dettagli dei libri e degli autori. Qui impareremo le generic class-based views, e mostreremo come possono ridurre l'ammontare di codice da scrivere per i casi d'uso comuni. Vedremo anche la gestione degli URL in modo più approfondito, mostrando come effettuare un pattern matching di base.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/Sessions">Django Tutorial Parte 7: Sessions framework</a></dt> + <dd>Questo tutorial estende il nostro sito <em>LocalLibrary</em>, aggiungendo un contatore delle visite basatoi sulle sessioni nella home page. Questo è un esempio relativamente semplice, ma mostra come è possibile utilizzare il session framework per fornire comportamenti persistenti agli utenti anonimi nei propri siti.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/Authentication">Django Tutorial Parte 8: Autenticazione utenti e permessi</a></dt> + <dd>In questo tutorial ti mostreremo come consentire agli utenti di accedere al tuo sito con i loro account e come controllare cosa possono fare e vedere in base al fatto che siano o meno connessi e in base alle loro <em>permissions</em>. Come parte di questa dimostrazione estenderemo il sito <em>LocalLibrary</em>, aggiungendo pagine di accesso e logout e pagine specifiche dell'utente e del personale per la visualizzazione di libri presi in prestito.</dd> + <dt><a href="/it/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Lavorare con i forms</a></dt> + <dd>In questo tutorial ti mostreremo come lavorare con i <a href="/it/docs/Web/Guide/HTML/Forms">Forms HTML</a> in Django, e in particolare il modo più semplice per scrivere forms per creare, aggiornare ed eliminare le istanze del model. Come parte di questa dimostrazione estenderemo il sito <em>LocalLibrary</em> in modo che i bibliotecari possano rinnovare i libri e creare, aggiornare ed eliminare gli autori utilizzando i nostri forms (anziché utilizzare l'applicazione di admin).</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></dt> + <dd>As websites grow they become harder to test manually — not only is there more to test, but, as the interactions between components become more complex, a small change in one area can require many additional tests to verify its impact on other areas. One way to mitigate these problems is to write automated tests, which can easily and reliably be run every time you make a change. This tutorial shows how to automate <em>unit testing</em> of your website using Django's test framework.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></dt> + <dd>Now you've created (and tested) an awesome <em>LocalLibrary</em> website, you're going to want to install it on a public web server so that it can be accessed by library staff and members over the Internet. This article provides an overview of how you might go about finding a host to deploy your website, and what you need to do in order to get your site ready for production.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></dt> + <dd>Protecting user data is an essential part of any website design. We previously explained some of the more common security threats in the article <a href="https://developer.mozilla.org/en-US/docs/Web/Security">Web security</a> — this article provides a practical demonstration of how Django's in-built protections handle such threats.</dd> +</dl> + +<h2 id="Assessments">Assessments</h2> + +<p>The following assessment will test your understanding of how to create a website using Django, as described in the guides listed above.</p> + +<dl> + <dt><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></dt> + <dd>In this assessment you'll use some of the knowledge you've learned from this module to create your own blog.</dd> +</dl> diff --git a/files/it/learn/server-side/django/introduzione/index.html b/files/it/learn/server-side/django/introduzione/index.html new file mode 100644 index 0000000000..4eb36683eb --- /dev/null +++ b/files/it/learn/server-side/django/introduzione/index.html @@ -0,0 +1,281 @@ +--- +title: Introduzione a Django +slug: Learn/Server-side/Django/Introduzione +tags: + - Introduzione + - Learn + - Principianti + - Python + - django + - programmazione lato server +translation_of: Learn/Server-side/Django/Introduction +--- +<div>{{LearnSidebar}}</div> + +<div>{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}</div> + +<div><span class="seoSummary">In questo primo articolo su Django risponderemo alla domanda "Cos'è Django?" e forniremo una panoramica su cosa rende speciale questo web framework. Andremo a sottolinearne le principali caratteristiche, incluse alcune delle funzionalità avanzate, che però in questo modulo non avremo tempo di presentare nel dettaglio.</span> Mostreremo poi alcuni dei principali blocchi che compongono un'applicazione Django (sebbene a questo punto non dovreste ancora avere un ambiente di sviluppo in cui poterla testare).</div> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td> + <p>Conoscenza base del computer. Un'introduzione generale alla <a href="https://developer.mozilla.org/it/docs/Learn/Server-side/First_steps">programmazione lato server</a>, in particolare ai <a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">meccanismi di interazione client-server</a>.</p> + </td> + </tr> + <tr> + <th scope="row">Obiettivo:</th> + <td>Acquisire familiarità con l'ambiente Django: cos'è, come funziona, quali sono le principali funzionalità che mette a disposizione e i blocchi principali delle applicazioni Django.</td> + </tr> + </tbody> +</table> + +<h2 id="Che_cosè_Django">Che cos'è Django?</h2> + +<p>Django è un framework web Python di alto livello che consente un rapido sviluppo di siti web sicuri e manutenibili. Costruito da sviluppatori esperti, Django si occupa di gran parte del problema dello sviluppo web, in modo da potersi concentrare sulla scrittura della propria app senza dover reinventare la ruota. È gratuito e open source, ha una comunità fiorente e attiva, un'ottima documentazione e molte opzioni per il supporto gratuito e a pagamento. </p> + +<p>Django vi aiuta a scrivere software che è:</p> + +<dl> + <dt>Completo</dt> + <dd>Django segue la filosofia "Batterie incluse" e fornisce quasi tutto ciò che gli sviluppatori potrebbero voler fare "out of the box". Poiché tutto ciò di cui si ha bisogno è parte di un unico "prodotto", funziona tutto insieme senza soluzione di continuità, segue principi di progettazione coerenti e ha una vasta e <a href="https://docs.djangoproject.com/en/stable/">aggiornata documentazione</a>.</dd> + <dt>Versatile</dt> + <dd>Django può essere (ed è stato) utilizzato per costruire quasi ogni tipo di sito web - dai sistemi di gestione dei contenuti e wiki, fino ai social network e ai siti di notizie. Può funzionare con qualsiasi framework lato client, e può fornire contenuti in quasi tutti i formati (inclusi HTML, feed RSS, JSON, XML, ecc.). Il sito che state leggendo è basato su Django!</dd> + <dd>Internamente, mentre fornisce scelte per quasi tutte le funzionalità che si possono desiderare (ad esempio, diversi database popolari, motori di modellizzazione, ecc), può anche essere esteso per utilizzare altri componenti se necessario.</dd> + <dt>Sicuro</dt> + <dd>Django aiuta gli sviluppatori ad evitare molti errori di sicurezza comuni, fornendo un framework che è stato progettato per "fare le cose giuste" per proteggere automaticamente il sito web. Ad esempio, Django fornisce un modo sicuro per gestire gli account utente e le password, evitando i comuni errori come l'inserimento di informazioni di sessione nei cookie dove sono vulnerabili (i cookie contengono solo una chiave e i dati reali sono memorizzati nel database) o la memorizzazione diretta delle password piuttosto che l'hash della password.</dd> + <dd><em>Un hash della password è un valore di lunghezza fissa creato inviando la password attraverso una <a href="https://en.wikipedia.org/wiki/Cryptographic_hash_function">funzione di hash crittografico</a>. Django può controllare se una password inserita è corretta eseguendola attraverso la funzione hash e confrontando l'uscita con il valore hash memorizzato. Tuttavia, a causa della natura "unidirezionale" della funzione, anche se un valore hash memorizzato è compromesso, è difficile per un aggressore elaborare la password originale.</em></dd> + <dd>Django consente la protezione contro molte vulnerabilità di default, tra cui SQL injection, cross-site scripting, cross-site request forgery e clickjacking (vedere <a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Sicurezza del sito web</a> per maggiori dettagli su tali attacchi).</dd> + <dt>Scalabile</dt> + <dd>Django utilizza un'architettura basata su componenti "shared-nothing" (ogni parte dell'architettura è indipendente dalle altre e può quindi essere sostituita o modificata se necessario). Avere una chiara separazione tra le diverse parti significa che può scalare per l'aumento del traffico aggiungendo hardware a qualsiasi livello: server di caching, server di database o server di applicazioni. Alcuni dei siti più trafficati hanno scalato con successo Django per soddisfare le loro richieste (ad esempio Instagram e Disqus, per citarne solo due).</dd> + <dt>Manutenibile</dt> + <dd>Il codice Django è scritto utilizzando principi di progettazione e modelli che incoraggiano la creazione di codice manutenibile e riutilizzabile. In particolare, si avvale del principio Don't Repeat Yourself (DRY) per evitare inutili duplicazioni, riducendo la quantità di codice. Django promuove anche il raggruppamento delle funzionalità correlate in "applicazioni" riutilizzabili e, ad un livello più basso, raggruppa il codice correlato in moduli (sulla falsariga del modello Model View Controller (MVC)).</dd> + <dt>Portabile</dt> + <dd>Django è scritto in Python, che funziona su molte piattaforme. Ciò significa che non siete legati a nessuna particolare piattaforma server e potete eseguire le vostre applicazioni su molti tipi di Linux, Windows e Mac OS X. Inoltre, Django è ben supportato da molti web hosting provider, che spesso forniscono infrastrutture e documentazione specifiche per l'hosting dei siti Django.</dd> +</dl> + +<h2 id="Da_dove_proviene">Da dove proviene?</h2> + +<p>Django è stato inizialmente sviluppato tra il 2003 e il 2005 da un team web che si occupava della creazione e della manutenzione dei siti web dei giornali. Dopo aver creato un certo numero di siti, il team ha iniziato a elaborare e riutilizzare un sacco di codice e modelli di design comuni. Questo codice comune si è evoluto in un generico framework di sviluppo web, che è stato "open-sourced" come progetto "Django" nel luglio 2005. </p> + +<p>Django ha continuato a crescere e migliorare, dalla sua prima release milestone (1.0) nel settembre 2008 fino alla recente versione 2.0 (2017). Ogni release ha aggiunto nuove funzionalità e correzioni di bug, che vanno dal supporto per nuovi tipi di database, motori di template e caching, fino all'aggiunta di funzioni di visualizzazione e classi "generiche" (che riducono la quantità di codice che gli sviluppatori devono scrivere per una serie di attività di programmazione). </p> + +<div class="note"> +<p><strong>Nota</strong>: Date un'occhiata alle <a href="https://docs.djangoproject.com/en/stable/releases/">note di rilascio</a> sul sito web di Django per vedere cosa è cambiato nelle ultime versioni, e quanto lavoro si sta facendo per rendere Django migliore.</p> +</div> + +<p>Django è ora un progetto open source fiorente e collaborativo, con molte migliaia di utenti e collaboratori. Pur avendo ancora alcune caratteristiche che riflettono la sua origine, Django si è evoluto in un framework versatile in grado di sviluppare qualsiasi tipo di sito web. </p> + +<h2 id="Quanto_è_popolare_Django">Quanto è popolare Django?</h2> + +<p>Non c'è una misura disponibile e definitiva della popolarità dei framework lato server (anche se siti come <a href="http://hotframeworks.com/">Hot Frameworks</a> tentano di valutare la popolarità usando meccanismi come il conteggio del numero di progetti GitHub e le domande di StackOverflow per ogni piattaforma). Una domanda migliore è se Django è "abbastanza popolare" per scongiurare i problemi delle piattaforme poco popolari. Continua ad evolversi? Puoi chiedere aiuto se ne hai bisogno? C'è la possibilità di ottenere un lavoro retribuito se si impara Django? </p> + +<p>In base al numero di siti di alto profilo che utilizzano Django, al numero di persone che contribuiscono al codice e al numero di persone che forniscono supporto sia gratuito che a pagamento, allora sì, Django è un framework popolare!</p> + +<p>I siti di alto profilo che utilizzano Django includono: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest e Open Stack (fonte: <a href="https://www.djangoproject.com/">home page di Django</a>).</p> + +<h2 id="Django_è_dogmatico">Django è dogmatico?</h2> + +<p>I framework web spesso si riferiscono a se stessi come "dogmatici" o "non dogmatici".</p> + +<p>I framework dogmatici sono quelli che hanno dogmi sul "giusto modo" di gestire un particolare compito. Spesso supportano un rapido sviluppo in un particolare dominio (risolvere problemi di un particolare tipo) perché il modo giusto di fare qualsiasi cosa è di solito ben compreso e ben documentato. Tuttavia possono essere meno flessibili nel risolvere i problemi al di fuori del loro dominio principale e tendono ad offrire meno scelte per quali componenti e approcci si possono utilizzare.</p> + +<p>I framework non dogmatici, al contrario, hanno molte meno restrizioni sul modo migliore per collegare i componenti per raggiungere un obiettivo, o anche su quali componenti usare. Con essi è più facile per gli sviluppatori utilizzare gli strumenti più adatti per completare un particolare compito, al anche se devono sostenere un dispendio di energie per trovare da soli quei componenti.</p> + +<p>Django è "mediamente dogmatico", e quindi fornisce il "meglio di entrambi i mondi". Fornisce un insieme di componenti per gestire la maggior parte dei compiti di sviluppo web e uno (o due) modi preferiti per utilizzarli. Tuttavia, l'architettura disaccoppiata di Django significa che di solito è possibile scegliere tra una serie di opzioni diverse, o, se lo si desidera, aggiungere il supporto per quelle completamente nuove.</p> + +<h2 id="Che_aspetto_ha_il_codice_di_Django">Che aspetto ha il codice di Django?</h2> + +<p>In un sito web tradizionale basato su dati, un'applicazione web attende le richieste HTTP dal browser web (o da un altro client). Quando una richiesta viene ricevuta, l'applicazione elabora ciò che è necessario in base all'URL ed eventualmente alle informazioni contenute nei dati <code>POST </code>o nei dati <code>GET</code>. A seconda di ciò che è richiesto, può quindi leggere o scrivere informazioni da un database o eseguire altri compiti necessari per soddisfare la richiesta. L'applicazione restituisce quindi una risposta al browser web, spesso creando dinamicamente una pagina HTML che il browser può visualizzare inserendo i dati recuperati nei segnaposto in un modello HTML.</p> + +<p>Le applicazioni web Django tipicamente raggruppano il codice che gestisce ciascuno di questi passaggi in file separati:<img alt="" src="https://mdn.mozillademos.org/files/13931/basic-django.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p> + +<ul> + <li><strong>URLs: </strong>Mentre è possibile elaborare le richieste da ogni singolo URL tramite una singola funzione, è molto più gestibile scrivere una funzione di visualizzazione separata per gestire ogni risorsa. Un mappatore di URL viene utilizzato per reindirizzare le richieste HTTP alla vista appropriata in base all'URL della richiesta. Il mappatore URL può anche abbinare particolari modelli di stringhe o cifre che appaiono in un URL, e passarli a una funzione di visualizzazione come dati.<br> + <strong>View:</strong> Una vista è una funzione di gestione delle richieste, che riceve le richieste HTTP e restituisce le risposte HTTP. Le viste accedono ai dati necessari per soddisfare le richieste tramite modelli (<em>models</em>) e delegano la formattazione della risposta ai <em>templates</em>.</li> + <li><strong>Models:</strong> I modelli sono oggetti Python che definiscono la struttura dei dati di un'applicazione e forniscono meccanismi per gestire (aggiungere, modificare, cancellare) e interrogare i record nel database. </li> + <li><strong>Templates:</strong>Un template è un file di testo che definisce la struttura o il layout di un file (come una pagina HTML), con segnaposto utilizzati per rappresentare il contenuto effettivo. Una vista (<em>view</em>) può creare dinamicamente una pagina HTML utilizzando un template HTML, popolandola con i dati di un modello (<em>model</em>). Un template può essere utilizzato per definire la struttura di qualsiasi tipo di file; non deve essere necessariamente HTML!</li> +</ul> + +<div class="note"> +<p><strong>Nota</strong>: Django si riferisce a questa organizzazione come all'architettura "Model View Template (MVT)". Ha molte somiglianze con la più familiare architettura del <a href="/en-US/docs/Web/Apps/Fundamentals/Modern_web_app_architecture/MVC_architecture">Model View Controller</a>.</p> +</div> + +<ul> +</ul> + +<p>Le sezioni seguenti vi daranno un'idea di come sono fatte queste parti principali di un'applicazione Django (approfondiremo i dettagli più avanti nel corso, una volta creato un ambiente di sviluppo).</p> + +<h3 id="Inviare_la_richiesta_alla_vista_giusta_urls.py">Inviare la richiesta alla vista giusta (urls.py)</h3> + +<p>Un URL mapper è tipicamente memorizzato in un file chiamato <strong>urls.py</strong>. Nell'esempio seguente, il mapper (<code>urlpatterns</code>) definisce una lista di mappature tra le routes (specifici URL <em>patterns</em> ) e le corrispondenti funzioni di visualizzazione (<em>view</em>). Se viene ricevuta una richiesta HTTP che ha un URL che corrisponde a uno specifico <em>pattern</em>, allora la funzione di <em>view</em> associata sarà chiamata e passerà la richiesta.</p> + +<pre class="notranslate">urlpatterns = [ + <strong>path('admin/', admin.site.urls), + </strong>path('book/<int:id>/', views.book_detail, name='book_detail'), + path('catalog/', include('catalog.urls')), + re_path(r'^([0-9]+)/$', views.best), +] +</pre> + +<p>L'oggetto <code>urlpatterns </code>è una lista di funzioni <code>path()</code> e/o<code> re_path()</code> (le liste Python sono definite usando parentesi quadre, dove gli elementi sono separati da virgole e possono avere una virgola di tracciamento opzionale. Per esempio: <code>[item1, item2, item3,]</code>).</p> + +<p>Il primo argomento per entrambi i metodi è il percorso (<em>pattern</em>) che sarà abbinato. Il metodo <code>path()</code> usa le parentesi angolari per definire le parti di un URL che saranno catturate e passate alla funzione di visualizzazione come argomenti. La funzione <code>re_path()</code> usa un approccio flessibile per la corrispondenza dei pattern, noto come espressione regolare. Ne parleremo in un articolo successivo!</p> + +<p>Il secondo argomento è la funzione che viene chiamata in abbinamento al pattern. La notazione <code>views.book_detail</code> indica che la funzione chiamata <code>book_detail()</code> può essere trovata in un modulo chiamato <code>views</code> (cioè all'interno di un file chiamato <code>views.py</code>)</p> + +<h3 id="Gestione_della_richiesta_views.py">Gestione della richiesta (views.py)</h3> + +<p>Le <em>views </em>sono il cuore dell'applicazione web, ricevono le richieste HTTP dai client web e restituiscono le risposte HTTP. Nel mezzo, esse mettono a disposizione le altre risorse del framework per accedere ai database, rendere i modelli, ecc. </p> + +<p>L'esempio seguente mostra una minima funzione di view <code>index()</code>, che avrebbe potuto essere chiamata dal nostro URL mapper nella sezione precedente. Come tutte le funzioni di view riceve un oggetto <code>HttpRequest </code>come parametro (<code>request</code>) e restituisce un oggetto <code>HttpResponse</code>. In questo caso non facciamo nulla con la richiesta, e la nostra risposta restituisce semplicemente una stringa codificata. Vi mostreremo una richiesta che fa qualcosa di più interessante in una sezione successiva.</p> + +<pre class="brush: python notranslate"># filename: views.py (Django view functions) + +from django.http import HttpResponse + +def index(request): + # Get an HttpRequest - the request parameter + # perform operations using information from the request. + # Return HttpResponse + return HttpResponse('Hello from Django!') +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Un po' di Python:</p> + +<ul> + <li><a href="https://docs.python.org/3/tutorial/modules.html">I moduli Python </a>sono "librerie" di funzioni, memorizzate in file separati, che potremmo voler utilizzare nel nostro codice. Qui importiamo solo l'oggetto <code>HttpResponse </code>dal modulo <code>django.http</code> in modo da poterlo usare nella nostra view: <code>from django.http import HttpResponse</code> . Ci sono altri modi per importare alcuni o tutti gli oggetti da un modulo.</li> + <li>Le funzioni sono dichiarate usando la parola chiave <code>def </code>come mostrato sopra, con i parametri denominati elencati tra parentesi dopo il nome della funzione; la riga finisce con i due punti. Si noti come le righe successive sono tutte indentate. L'indentazione è importante, in quanto specifica che le linee di codice sono all'interno di quel particolare blocco (l'indentazione obbligatoria è una caratteristica chiave di Python, ed è uno dei motivi per cui il codice Python è così facile da leggere).</li> +</ul> +</div> + +<ul> +</ul> + +<p>Le views sono solitamente salvate in un file chiamato <strong>views.py</strong>.</p> + +<h3 id="Definizione_dei_modelli_di_dati_models.py">Definizione dei modelli di dati (models.py)</h3> + +<p>Le applicazioni web Django gestiscono e interrogano i dati attraverso oggetti Python chiamati modelli (<em>models</em>). I modelli definiscono la struttura dei dati memorizzati, inclusi i tipi di campo ed eventualmente anche la loro dimensione massima, i valori di default, le opzioni della lista di selezione, il testo di aiuto per la documentazione, il testo dell'etichetta per i moduli, ecc. La definizione del modello è indipendente dal database sottostante - è possibile scegliere uno dei diversi modelli come parte delle impostazioni del progetto. Una volta scelto il database che si vuole utilizzare, non è necessario parlare direttamente con esso - basta scrivere la struttura del modello e altro codice, e Django si occupa per voi di tutto il lavoro sporco di comunicazione con il database.</p> + +<p>Il frammento di codice qui sotto mostra un modello Django molto semplice per un oggetto <code>Team</code>. La classe <code>Team </code>è derivata dalla classe django <code>model.Model</code>. Essa definisce il nome del team e il livello del team come campi di caratteri e specifica un numero massimo di caratteri da memorizzare per ogni record. Il <code>team_level</code> può essere uno dei diversi valori, quindi lo definiamo come un campo di scelta e forniamo una mappatura tra le scelte da visualizzare e i dati da memorizzare, insieme ad un valore predefinito. </p> + +<pre class="brush: python notranslate"># filename: models.py + +from django.db import models + +class Team(models.Model): + team_name = models.CharField(max_length=40) + + TEAM_LEVELS = ( + ('U09', 'Under 09s'), + ('U10', 'Under 10s'), + ('U11', 'Under 11s'), + ... #list other team levels + ) + team_level = models.CharField(max_length=3, choices=TEAM_LEVELS, default='U11') +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Un po' di Python:</p> + +<ul> + <li> + <p>Python supporta la "programmazione orientata agli oggetti" (object-oriented programming<em> - </em>OOP <em>ndt</em>), uno stile di programmazione in cui organizziamo il nostro codice in oggetti, che includono dati e funzioni correlate per operare su quei dati. Gli oggetti possono anche ereditare/estendere/derivare da altri oggetti, permettendo di condividere il comportamento comune tra oggetti correlati. In Python usiamo la parola chiava <code>class </code>per definire un "prototipo" (<em>blueprint - ntd</em>) di un oggetto. Possiamo creare più <em>istanze </em>specifiche del tipo di oggetto in base al modello nella classe.</p> + + <p>Così, per esempio, qui abbiamo una classe <code>Team</code>, che deriva dalla classe <code>Model</code>. Questo significa che è un modello, e che conterrà tutti i metodi di un modello, ma possiamo anche dargli caratteristiche specializzate proprie. Nel nostro modello definiamo i campi di cui il nostro database avrà bisogno per memorizzare i nostri dati, dando loro nomi specifici. Django utilizza queste definizioni, compresi i nomi dei campi, per creare il database sottostante.</p> + </li> +</ul> +</div> + +<h3 id="Interrogare_i_dati_views.py">Interrogare i dati (views.py)</h3> + +<p>Il modello Django fornisce una semplice API di interrogazione per la ricerca nel database. Questa può essere confrontata con una serie di campi alla volta utilizzando diversi criteri (ad es. esatto, non sensibile alle maiuscole, maggiore di, ecc.), e può supportare affermazioni complesse (ad esempio, è possibile specificare una ricerca su squadre U11 che hanno un nome di squadra che inizia con "Fr" o finisce con "al"). </p> + +<p>Il frammento di codice mostra una funzione di visualizzazione (gestore di risorse) per la visualizzazione di tutti i nostri team U09. La linea in grassetto mostra come possiamo usare l'API della query del modello per filtrare per tutti i record dove il campo <code>team_level</code> ha esattamente il testo 'U09' (notare come questo criterio è passato alla funzione <code>filter()</code> come argomento con il nome del campo e il tipo di match separati da un doppio underscore: <strong>team_level__exact</strong>).</p> + +<pre class="brush: python notranslate">## filename: views.py + +from django.shortcuts import render +from .models import Team + +def index(request): + <strong>list_teams = Team.objects.filter(team_level__exact="U09")</strong> + context = {'youngest_teams': list_teams} + return render(request, '/best/index.html', context) +</pre> + +<dl> +</dl> + +<p>Questa funzione utilizza la funzione <code>render()</code> per creare la <code>HttpResponse </code>che viene inviata al browser. Questa funzione è una <em>scorciatoia</em>; crea un file HTML combinando un template HTML specificato e alcuni dati da inserire nel template (forniti nella variabile denominata "<code>context</code>"). Nella sezione successiva mostriamo come il template ha i dati inseriti per creare l'HTML.</p> + +<h3 id="Visualizzazione_dei_dati_HTML_templates">Visualizzazione dei dati (HTML templates)</h3> + +<p>I sistemi di template consentono di specificare la struttura di un documento di output, utilizzando dei segnaposto per i dati che verranno compilati al momento della generazione di una pagina. I template sono spesso usati per creare HTML, ma possono anche creare altri tipi di documenti. Django supporta sia il suo sistema di template nativo che un'altra popolare libreria Python chiamata Jinja2 out of the box (può anche essere realizzata per supportare altri sistemi se necessario). </p> + +<p>Il frammento di codice mostra come potrebbe apparire il template HTML chiamato dalla funzione <code>render()</code> nella sezione precedente. Questo template è stato scritto partendo dal presupposto che avrà accesso ad una variabile di lista chiamata <code>youngest_teams</code> al momento del rendering (contenuta nella variabile <code>context </code>all'interno della funzione <code>render()</code> di cui sopra). All'interno dello scheletro HTML abbiamo un'espressione che prima controlla se la variabile <code>youngest_teams</code> esiste, e poi la itera in un ciclo <code>for</code>. Su ogni iterazione il template mostra il valore <code>team_name</code> di ogni squadra in un elemento {{htmlelement("li")}}.</p> + +<pre class="brush: python notranslate">## filename: best/templates/best/index.html + +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Home page</title> +</head> +<body> + {% if youngest_teams %} + <ul> + {% for team in youngest_teams %} + <li>\{\{ team.team_name \}\}</li> + {% endfor %} + </ul> + {% else %} + <p>No teams are available.</p> + {% endif %} +</body> +</html></pre> + +<h2 id="Cosaltro_si_può_fare">Cos'altro si può fare?</h2> + +<p>Le sezioni precedenti mostrano le principali caratteristiche che utilizzerete in quasi tutte le applicazioni web: URL mapping, views, modelli e templates. Solo alcune delle altre cose fornite da Django includono: </p> + +<ul> + <li><strong>Forms</strong>: I forms HTML sono utilizzati per raccogliere i dati degli utenti per l'elaborazione sul server. Django semplifica la creazione, la validazione e l'elaborazione dei moduli.</li> + <li><strong>L'autenticazione dell'utente e i permessi</strong>: Django include un robusto sistema di autenticazione degli utenti e di permessi che è stato costruito pensando alla sicurezza. </li> + <li><strong>Caching</strong>: La creazione dinamica dei contenuti è molto più intensa (e lenta) dal punto di vista computazionale rispetto ai contenuti statici. Django fornisce una cache flessibile in modo da poter memorizzare tutta o parte di una pagina renderizzata in modo che non venga riprodotta, tranne quando necessario.</li> + <li><strong>Sito di amministrazione</strong>: Il sito di amministrazione di Django è incluso di default quando si crea un'applicazione utilizzando lo scheletro di base. Rende banalmente facile fornire una pagina di amministrazione per gli amministratori del sito per creare, modificare e visualizzare qualsiasi modello di dati nel vostro sito</li> + <li><strong>Serialising </strong> Django rende facile serializzare e servire i vostri dati come XML o JSON. Questo può essere utile quando si crea un servizio web (un sito web che serve esclusivamente dati da consumare da altre applicazioni o siti, e non visualizza nulla di per sé), o quando si crea un sito web in cui il codice lato client gestisce tutti i rendering dei dati.</li> +</ul> + +<h2 id="Sommario">Sommario</h2> + +<p>Congratulazioni, hai completato il primo passo del tuo viaggio Django! Ora dovreste aver compreso i principali vantaggi di Django, un po' della sua storia e più o meno come potrebbero essere le parti principali di un'applicazione Django. Dovreste anche aver imparato alcune cose sul linguaggio di programmazione Python, compresa la sintassi per le liste, le funzioni e le classi.</p> + +<p>Avete già visto un po' di vero codice Django qui sopra, ma a differenza del codice lato client, è necessario impostare un ambiente di sviluppo per eseguirlo. Questo è il nostro prossimo passo.<br> + </p> + +<div>{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}</div> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/it/docs/Learn/Server-side/Django/Introduzione">Django introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> diff --git a/files/it/learn/server-side/django/models/index.html b/files/it/learn/server-side/django/models/index.html new file mode 100644 index 0000000000..ec3554f577 --- /dev/null +++ b/files/it/learn/server-side/django/models/index.html @@ -0,0 +1,466 @@ +--- +title: 'Django Tutorial Part 3: Using models' +slug: Learn/Server-side/Django/Models +tags: + - Articolo + - Dati + - Model + - Server + - Tutorial + - data + - django + - imparare + - lezione + - modello + - nuovo +translation_of: Learn/Server-side/Django/Models +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django")}}</div> + +<p class="summary">Questo articolo mostra come definire dei modelli per il sito della <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>. Spiega cos'è un modello, come viene dichiarato e alcuni dei principali tipi di campo. Mostra anche brevemente alcuni dei principali modi in cui è possibile accedere ai dati del modello.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a>.</td> + </tr> + <tr> + <th scope="row">Obbiettivi:</th> + <td>Essere in grado di progettare e creare i propri modelli, scegliendo i campi in modo appropriato.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica">Panoramica</h2> + +<p>Le applicazioni web Django accedono e gestiscono i dati tramite oggetti Python denominati modelli. I modelli definiscono la <em>struttura </em>dei dati memorizzati, inclusi i <em>tipi </em>di campo e possibilmente anche la loro dimensione massima,valori predefiniti, opzioni dell'elenco di selezione, testo di aiuto per la documentazione, testo della label per i moduli, ecc. La definizione del modello è indipendente dal database sottostante: è possibile sceglierne uno tra i diversi come parte delle impostazioni del progetto. Una volta scelto il database che si desidera utilizzare, non è necessario interrogarlo direttamente, basta scrivere la struttura del modello e altro codice, e Django gestirà tutto il lavoro sporco di comunicazione con il database.</p> + +<p>Questo tutorial mostra come definire e accedere ai modelli per l'esempio del <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary website</a>.</p> + +<h2 id="Progettare_i_model_per_la_LocalLibrary">Progettare i model per la LocalLibrary</h2> + +<p>Prima di saltare e iniziare a codificare i modelli, vale la pena dedicare alcuni minuti a pensare a quali dati dobbiamo memorizzare e alle relazioni tra i diversi oggetti.</p> + +<p>Sappiamo che abbiamo bisogno di memorizzare informazioni sui libri (titolo, sommario, autore, lingua scritta, categoria, ISBN) e che potremmo avere più copie disponibili (con ID unico globale, stato di disponibilità, ecc.). Potremmo aver bisogno di memorizzare più informazioni sugli autori oltre al loro nome e potrebbero esserci più autori con nomi uguali o simili. Vogliamo essere in grado di ordinare le informazioni in base al titolo del libro, autore, lingua scritta e categoria.</p> + +<p>Quando si progettano i modelli, è logico disporre di modelli separati per ogni "oggetto" (un gruppo di informazioni correlate). In questo caso gli oggetti ovvi sono i libri, le istanze di libri e gli autori</p> + +<p>Potresti anche voler utilizzare i modelli per rappresentare delle opzioni per un elenco di selezione (ad esempio, come un elenco a discesa), piuttosto che codificare le scelte nel sito stesso - questo è consigliato quando tutte le opzioni non sono note in anticipo o potrebbero essere modificate. I candidati ovvi per i modelli in questo caso includono il genere di libro (ad esempio Fantascienza, Poesia francese, ecc.) e la lingua (Inglese, Francese, Giapponese).</p> + +<p>Una volta che abbiamo deciso i nostri modelli e i nostri campi, dobbiamo pensare alle relazioni. Django ti permette di definire relazioni che sono uno a uno (<strong><em>OneToOneField</em></strong>), uno a molti (<em><strong>ForeignKey</strong></em>) e molti a molti (<em><strong>ManyToManyField</strong></em>).Con questo in mente, lo schema di associazione UML qui sotto mostra i modelli che definiremo in questo caso (come schede).</p> + +<p><img alt="LocalLibrary Model UML" src="https://mdn.mozillademos.org/files/16479/local_library_model_uml.png" style="height: 660px; width: 977px;"></p> + +<p>Come sopra, abbiamo creato modelli per book (i dettagli generici del libro), per book instance (lo stato di specifiche copie fisiche del libro disponibile nel sistema) e author. Abbiamo anche deciso di avere un modello per il genere (genre), in modo che i valori possano essere creati/selezionati attraverso l'interfaccia di amministrazione. Abbiamo deciso di non avere un modello per <code>BookInstance:status</code> - abbiamo codificato i valori (<code>LOAN_STATUS</code>) perché non ci aspettiamo che questi cambino. All'interno di ciascuna casella è possibile visualizzare il nome del model, i nomi dei campi e i tipi, nonché i metodi e i relativi tipi di ritorno.</p> + +<p>Il diagramma mostra anche le relazioni tra i modelli, incluse le loro <em>molteplicità</em>. Le molteplicità sono i numeri sul diagramma che mostrano i numeri (massimo e minimo) di ciascun modello che può essere presente nella relazione. Ad esempio, la linea di collegamento tra le caselle mostra che Book e un Genre sono correlati. I numeri vicino al modello Genre mostrano che un Book deve avere uno o più Genres (quanti ne vuoi), mentre i numeri all'altro capo della riga accanto al model Book mostrano che un Genre può avere zero o molti Books associati.</p> + +<div class="note"> +<p><strong>Nota</strong>: La prossima sezione fornisce un manuale di base che spiega come vengono definiti e utilizzati i models. Mentre lo leggi, considera come costruiremo ciascuno dei modelli nel diagramma sopra.</p> +</div> + +<h2 id="Fondamenti_del_modello">Fondamenti del modello</h2> + +<p>Questa sezione fornisce una breve panoramica di come viene definito un model e alcuni dei campi e argomenti di campo più importanti.</p> + +<h3 id="Definizione_del_modello">Definizione del modello</h3> + +<p>I model vengono generalmente definiti nel file <strong>models.py</strong> di una applicazione. Sono implementati come sottoclassi di <code>django.db.models.Model</code>, e possono includere campi, metodi e metadati. Il frammento di codice seguente mostra un modello "tipico", denominato <code>MyModelName</code>:</p> + +<pre>from django.db import models + +class MyModelName(models.Model): + """A typical class defining a model, derived from the Model class.""" + + # Fields + my_field_name = models.CharField(max_length=20, help_text='Enter field documentation') + ... + + # Metadata + class Meta: + ordering = ['-my_field_name'] + + # Methods + def get_absolute_url(self): + """Returns the url to access a particular instance of MyModelName.""" + return reverse('model-detail-view', args=[str(self.id)]) + + def __str__(self): + """String for representing the MyModelName object (in Admin site etc.).""" + return self.my_field_name</pre> + +<p>Nelle sezioni seguenti esploreremo in dettaglio ciascuna funzionalità all'interno del modello:</p> + +<h4 id="Campi">Campi</h4> + +<p>Un modello può avere un numero arbitrario di campi, di qualsiasi tipo - ognuno rappresenta una colonna di dati che vogliamo memorizzare in una delle nostre tabelle del database. Ogni record di database (riga) consisterà in uno di ciascun valore di quei campi. Osserviamo l'esempio seguente:</p> + +<pre class="brush: js">my_field_name = models.CharField(max_length=20, help_text='Enter field documentation')</pre> + +<p>Il nostro esempio precedente ha un singolo campo chiamato <code>my_field_name</code>, di tipo <code>models.CharField</code> — che significa che questo campo conterrà stringhe di caratteri alfanumerici. I tipi di campo vengono assegnati utilizzando classi specifiche, che determinano il tipo di record utilizzato per memorizzare i dati nel database, insieme ai criteri di convalida da utilizzare quando i valori vengono ricevuti da un form HTML (vale a dire ciò che costituisce un valore valido). I tipi di campo possono anche prendere argomenti che specificano ulteriormente come il campo è memorizzato o può essere utilizzato. In questo caso stiamo dando al nostro campo due argomenti:</p> + +<ul> + <li><code>max_length=20</code> — Indica che la lunghezza massima di un valore in questo campo è di 20 caratteri.</li> + <li><code>help_text='Enter field documentation'</code> — fornisce un'etichetta di testo da visualizzare per aiutare gli utenti a sapere quale valore fornire quando questo valore deve essere inserito da un utente tramite un form HTML.</li> +</ul> + +<p>Il nome del campo viene utilizzato per fare riferimento ad esso in query e templates. I campi hanno anche un'etichetta, che è specificata come argomento (<code>verbose_name</code>) o dedotto variando in maiuscola la prima lettera del nome della variabile del campo e sostituendo qualsiasi underscore con uno spazio (ad esempio <code>my_field_name</code> avrebbe una etichetta di default <em>My field name</em>).</p> + +<p>L'ordine in cui i campi sono dichiarati influenzerà il loro ordine predefinito se un modello viene reso in un modulo (ad esempio nel sito di amministrazione), tuttavia questo ordine può essere sovrascritto.</p> + +<h5 id="Argomenti_comuni_nei_campi">Argomenti comuni nei campi</h5> + +<p>I seguenti argomenti comuni possono essere utilizzati per dichiarare molti dei diversi tipi di campo:</p> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#help-text">help_text</a>: Fornisce un'etichetta di testo per i form HTML (ad esempio nel sito di amministrazione), come descritto sopra.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#verbose-name">verbose_name</a>: Un nome leggibile dall'uomo per il campo utilizzato nelle etichette di campo. Se non specificato, Django dedurrà il nome dettagliato predefinito dal nome del campo.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#default">default</a>: Il valore predefinito per il campo. Questo può essere un valore o un oggetto callable, nel qual caso l'oggetto verrà chiamato ogni volta che viene creato un nuovo record.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#null">null</a>: Se <code>True</code>, Django memorizzerà i valori bianchi come <code>NULL</code> nel database per i campi dove questo è appropriato (un campo <code>CharField</code> per esempio memorizzerà invece una stringa vuota). Per default è <code>False</code>.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#blank">blank</a>: Se <code>True</code>, il campo può essere vuoto nelle tue forme. L'impostazione predefinita è <code>False</code>, il che significa che la convalida del modulo di Django ti costringerà a inserire un valore. Spesso usato con <code>null=True</code> , perché se hai intenzione di consentire valori vuoti, vuoi anche che il database sia in grado di rappresentarli in modo appropriato.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#choices">choices</a>: Un gruppo di scelte per questo campo. Se viene fornito, il widget modulo corrispondente predefinito sarà una casella di selezione con queste scelte al posto del campo di testo standard.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#primary-key">primary_key</a>: Se <code>True</code>, imposta il campo corrente come chiave primaria per il modello (una chiave primaria è una colonna di database speciale designata per identificare in modo univoco tutti i diversi record di tabella). Se non viene specificato alcun campo come chiave primaria, Django aggiungerà automaticamente un campo per questo scopo.</li> +</ul> + +<p>Ci sono molte altre opzioni — consultare <a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-options">full list of field options here</a>.</p> + +<h5 id="Tipi_di_campo_più_comuni">Tipi di campo più comuni</h5> + +<p>Il seguente elenco descrive alcuni dei tipi di campi più comunemente usati.</p> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.CharField">CharField</a> è usato per definire stringhe di lunghezza fissa di dimensioni medio-piccole. Devi specificare il <code>max_length</code> dei dati memorizzati.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.TextField">TextField</a> viene utilizzato per stringhe di lunghezza arbitraria di grandi dimensioni. Puoi specificare la <code>max_length</code> per il campo, ma questo viene utilizzato solo quando il campo viene visualizzato nei moduli (non viene applicato a livello di database).</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.IntegerField" title="django.db.models.IntegerField">IntegerField</a> è un campo per la memorizzazione di valori interi (numero intero) e per la convalida di valori immessi come numeri interi nei moduli.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#datefield">DateField</a> e <a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#datetimefield">DateTimeField</a> sono utilizzati per storare/rappresentare date e data/time (in Python come oggetti <code>datetime.date</code> e <code>datetime.datetime</code>, rispettivamente). Questi campi possono essere dichiarati con dei parametri (mutualmente esclusivi) <code>auto_now=True</code> (per settare la data odierna automaticamente ogni volta che il modello viene salvato), <code>auto_now_add</code> (per settare la data solo quando il modello viene creato per la prima volta) , e <code>default</code> (per settare una data di default che possa essere sovrascritta dall'utente).</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#emailfield">EmailField</a> per storare e validare indirizzi mail.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#filefield">FileField</a> e <a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#imagefield">ImageField</a> per uploadare file e immagini rispettivamente (<code>ImageField</code> aggiunge semplicemente ulteriore convalida che il file caricato è un'immagine). Questi hanno parametri per definire come e dove sono memorizzati i file caricati.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#autofield">AutoField</a> tipologia speciale di <code>IntegerField</code> con autoincremento. Una chiave primaria di questo tipo viene automaticamente aggiunta al tuo modello se non ne specifichi esplicitamente una.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#foreignkey">ForeignKey</a> è usato per specificare una relazione uno-a-molti con un altro modello di database (ad esempio, un'auto ha un produttore, ma un produttore può fare molte automobili). Il lato "uno" della relazione è il modello che contiene la chiave.</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#manytomanyfield">ManyToManyField</a> è usato per specificare una relazione molti-a-molti (ad esempio un libro può avere diversi generi e ogni genere può contenere diversi libri). Nella nostra app di libreria li useremo in modo molto simile a <code>ForeignKeys</code>, ma possono essere usati in modi più complicati per descrivere le relazioni tra i gruppi. Questi hanno il parametro <code>on_delete</code> per definire cosa succede quando il record associato viene cancellato (ad esempio un valore <code>models.SET_NULL</code> setta il valore a <code>NULL</code>).</li> +</ul> + +<p>Esistono molti altri tipi di campi, compresi i campi per diversi tipi di numeri (interi grandi, interi piccoli, float), booleani, URL, slug, ID univoci e altre informazioni "temporali" (durata, tempo, ecc.) . È possibile visualizzare la <a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-types">full list here</a>.</p> + +<h4 id="Metadata">Metadata</h4> + +<p>Puoi dichiarare metadata per il tuo Modello utilizzando <code>class Meta</code>, come mostrato sotto.</p> + +<pre class="brush: python">class Meta: + ordering = ['-my_field_name'] +</pre> + +<p>Una delle funzionalità più utili di questi metadati consiste nel controllare l'ordinamento predefinito dei record restituiti quando si esegue una query sul tipo di modello. A tale scopo, specificare l'ordine di corrispondenza in un elenco di nomi di campi sull'attributo <code>ordering</code> come sopra. L'ordine dipende dal tipo di campo (i campi dei caratteri sono ordinati alfabeticamente, mentre i campi delle date sono ordinati in ordine cronologico). Come mostrato sopra, puoi anteporre il nome del campo al simbolo meno (-) per invertire l'ordine.</p> + +<p>Per esempio, se scegliamo un sort dei libri come nell'esempio per default:</p> + +<pre class="brush: python">ordering = ['title', '-pubdate']</pre> + +<p>i libri saranno ordinati alfabeticamente per titolo, dalla A alla Z e quindi per data di pubblicazione all'interno di ciascun titolo, dal più recente al più vecchio. Un altro attributo comune è <code>verbose_name</code>, un nome dettagliato per la classe in forma singolare e plurale:</p> + +<pre class="brush: python">verbose_name = 'BetterName'</pre> + +<p>Altri attributi utili consentono di creare e applicare nuove "autorizzazioni di accesso" per il modello (le autorizzazioni predefinite vengono applicate automaticamente), consentire l'ordinamento in base a un altro campo o dichiarare che la classe è "astratta" (una classe base per cui non è possibile creare record, e sarà invece derivato da creare altri modelli). Molte altre opzioni di metadati controllano quale database deve essere utilizzato per il modello e come vengono archiviati i dati (questi sono davvero utili solo se è necessario associare un modello a un database esistente).</p> + +<p>La lista completa di opzioni per i metadati: <a href="https://docs.djangoproject.com/en/2.1/ref/models/options/">Model metadata options</a> (Django docs).</p> + +<h4 id="Metodi">Metodi</h4> + +<p>Un modello può avere metodi.</p> + +<p><strong>In ogni caso, in ogni modello è necessario definire il metodo standard della classe Python <code>__str__()</code> per restituire una stringa leggibile dall'uomo per ciascun oggetto.</strong> Questa stringa viene utilizzata per rappresentare singoli record nel sito di amministrazione (e in qualsiasi altro punto è necessario fare riferimento a un'istanza del modello). Spesso questo restituirà un titolo o un campo nome dal modello.</p> + +<pre class="brush: python">def __str__(self): + return self.field_name</pre> + +<p>Un altro metodo comune da includere nei modelli Django è <code>get_absolute_url ()</code>, che restituisce un URL per la visualizzazione di record di modelli individuali sul sito Web (se si definisce questo metodo, Django aggiungerà automaticamente un pulsante "Visualizza sul sito" alle schermate di modifica dei record del modello in il sito di amministrazione). Di seguito viene mostrato un tipico pattern per <code>get_absolute_url ().</code></p> + +<pre class="brush: python">def get_absolute_url(self): + """Returns the url to access a particular instance of the model.""" + return reverse('model-detail-view', args=[str(self.id)]) +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Supponendo che utilizzerai URLs come <code>/myapplication/mymodelname/2</code> per visualizzare record individuali per il tuo modello (dove "2" è l'<code>id</code> per un particolare record), dovrai creare un mapper URL per passare la risposta e l'id a una "model detail view" (vista di dettaglio del modello) (che farà il lavoro richiesto per mostrare il record). la funzione <code>reverse()</code> sopra effettua un "reverse" del tuo url mapper (nel caso sopra nominato <em>'model-detail-view'</em>) per creare un URL nel formato corretto.</p> + +<p>Ovviamente per fare questo lavoro devi ancora scrivere la mappatura degli URL, la vista e il template!</p> +</div> + +<p>Puoi anche definire altri metodi che ti piacciono e chiamarli dal tuo codice o template (a condizione che non prendano alcun parametro).</p> + +<h3 id="Gestone_del_modello">Gestone del modello</h3> + +<p>Una volta definite le classi model, è possibile utilizzarle per creare, aggiornare o eliminare record e per eseguire query per ottenere tutti i record o particolari sottoinsiemi di record. Ti mostreremo come farlo nel tutorial quando definiremo le nostre views, ma ecco un breve sommario.</p> + +<h4 id="Creare_e_modificare_record">Creare e modificare record</h4> + +<p>Per creare un record puoi definire una istanza del modello e poi richiamare <code>save()</code>.</p> + +<pre class="brush: python"># Create a new record using the model's constructor. +record = MyModelName(my_field_name="Instance #1") + +# Save the object into the database. +record.save() +</pre> + +<div class="note"> +<p><strong>Note</strong>: Se non hai dichiarato alcun campo come <code>primary_key</code>, al nuovo record ne verrà assegnato uno automaticamente, con nome del campo <code>id</code>. È possibile interrogare questo campo dopo aver salvato il record precedente, esso dovrebbe avere il valore 1.</p> +</div> + +<p>È possibile accedere ai campi in questo nuovo record e modificarne i valori utilizzando la sintassi dot (.) e per memorizzare nel database i valori modificati devi chiamare <code>save()</code>.</p> + +<pre class="brush: python"># Access model field values using Python attributes. +print(record.id) # should return 1 for the first record. +print(record.my_field_name) # should print 'Instance #1' + +# Change record by modifying the fields, then calling save(). +record.my_field_name = "New Instance Name" +record.save()</pre> + +<h4 id="Ricercare_record">Ricercare record</h4> + +<p>È possibile cercare i record che soddisfano determinati criteri utilizzando l'attributo <code>objects</code> del model (fornito dalla classe base).</p> + +<div class="note"> +<p><strong>Nota</strong>: Spiegare come cercare i record usando il modello "astratto" nei nomi dei campi può generare un po 'di confusione. Nella discussione seguente faremo riferimento a un modello <code>Book</code> con campi <code>title</code> e <code>genre</code>, in cui genre è anche lui un modello con un singolo campo <code>name</code>.</p> +</div> + +<p>Possiamo ottenere tutti i record per un modello come un <code>QuerySet</code>, utilizzando<strong> </strong><code>objects.all()</code><strong>.</strong> Il <code>QuerySet</code> è un oggetto iterabile, ovvero contiene un numero di oggetti che è possibile scorrere/iterare/ciclare.</p> + +<pre class="brush: python">all_books = Book.objects.all() +</pre> + +<p>Il metodo <code>filter()</code> di Django ci consente di filtrare il <code>QuerySet</code> restituito per matchare un campo di testo o numerico specificato a un particolare criterio. Ad esempio, per filtrare i libri che contengono "wild" nel titolo e poi contarli, potremmo fare quanto segue.</p> + +<pre class="brush: python">wild_books = Book.objects.filter(title__contains='wild') +number_wild_books = wild_books.count() +</pre> + +<p>I campi da matchare e il tipo di corrispondenza sono definiti nel nome del parametro del filtro, utilizzando il formato: <code>field_name__match_type</code> (notare il <em>doppio underscore</em> tra <code>title</code> e <code>contains</code> sopra). In alto stiamo filtrando <code>title</code> con una corrispondenza case-sensitive. Esistono molti altri tipi di corrispondenze: <code>icontains</code> (case-insensitive), <code>iexact</code> (corrispondenza esatta case-insensitive), <code>exact</code> (corrispondenza esatta case-sensitive) e <code>in</code>, <code>gt</code> (grater than), <code>startswith</code>, ecc. Consultare la <a href="https://docs.djangoproject.com/en/2.1/ref/models/querysets/#field-lookups">lista completa qui</a>.</p> + +<p>In alcuni casi sarà necessario filtrare su un campo che definisce una relazione uno-a-molti con un altro modello (per esempio una <code>ForeignKey</code>). In questo caso è possibile "indicizzare" i campi all'interno del modello correlato con un doppio underscore aggiuntivo. Quindi, ad esempio, per filtrare i libri con uno specifico pattern genre, dovrai indicizzare al <code>name</code> attraverso il campo <code>genre</code>, come mostrato sotto:</p> + +<pre class="brush: python"># Will match on: Fiction, Science fiction, non-fiction etc. +books_containing_genre = Book.objects.filter(genre<strong>__</strong>name<strong>__</strong>icontains='fiction') +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Puoi usare gli underscores (__) per navigare su tutti i livelli di relazione che ti servono (<code>ForeignKey</code>/<code>ManyToManyField</code>). Per esempio, un <code>Book</code> che aveva diversi tipi, definiti utilizzando un'ulteriore relazione "cover" potrebbe avere un nome di parametro: <code>type__cover__name__exact='hard'.</code></p> +</div> + +<p>C'è molto di più che puoi fare con le query, comprese le ricerche all'indietro dai modelli correlati, concatenare i filtri, restituire un insieme più piccolo di valori, ecc. Per ulteriori informazioni, vedere <a href="https://docs.djangoproject.com/en/2.1/topics/db/queries/">Making queries</a> (Django Docs).</p> + +<h2 id="Definire_i_Models_della_LocalLibrary">Definire i Models della LocalLibrary</h2> + +<p>In questa sezione inizieremo a definire i modelli per la libreria. Apri <em>models.py</em> (in<em> /locallibrary/catalog/</em>). Le righe di codice iniziali importano il modulo <em>models</em>, che contiene la classe di base <code>models.Model</code> da cui i nostri modelli erediteranno.</p> + +<pre class="brush: python">from django.db import models + +# Create your models here.</pre> + +<h3 id="Modello_Genre">Modello Genre</h3> + +<p>Copia il codice del modello <code>Genre</code> mostrato sotto e incollalo alla fine del file <code>models.py</code>. Questo modello viene utilizzato per memorizzare informazioni sulla categoria di libri, ad esempio se si tratta di narrativa o saggistica, storia romantica o militare, ecc. Come menzionato sopra, abbiamo creato il Genre come model piuttosto che come testo libero o elenco di selezione <strong>in modo che i possibili valori possano essere gestiti tramite il database anziché essere hard-coded</strong>.</p> + +<pre class="brush: python">class Genre(models.Model): + """Model representing a book genre.""" + name = models.CharField(max_length=200, help_text='Enter a book genre (e.g. Science Fiction)') + + def __str__(self): + """String for representing the Model object.""" + return self.name</pre> + +<p>Il modello ha un singolo campo <code>CharField</code> (<code>name</code>), che descrive il genere (limitato a 200 caratteri e con un <code>help_text</code>. Alla fine del modello definiamo un metodo <code>__str__()</code>, che restituisce semplicemente il nome del genere definito da un particolare record. Nessun nome dettagliato (verbose) è stato definito, quindi il campo nel form verrà chiamato <code>Name</code>.</p> + +<h3 id="Modello_Book">Modello Book</h3> + +<p>Copia il modello Book in basso e incollalo nuovamente nella parte inferiore del file. Il modello del libro rappresenta tutte le informazioni su un libro disponibile in senso generale, ma non una particolare "istanza" fisica o "copia" disponibile per il prestito. Il modello usa un campo <code>CharField</code> per rappresentare <code>title</code> e <code>isbn</code> del libro (notare come <code>isbn</code> specifica la sua etichetta come "ISBN" utilizzando il primo parametro senza nome, in caso contrario la label di default sarebbe "Isbn"). Il modello usa <code>TextField</code> per il <code>summary</code>, perchè potrebbe essere un campo abbastanza lungo.</p> + +<pre class="brush: python">from django.urls import reverse # Used to generate URLs by reversing the URL patterns + +class Book(models.Model): + """Model representing a book (but not a specific copy of a book).""" + title = models.CharField(max_length=200) + + # Foreign Key used because book can only have one author, but authors can have multiple books + # Author as a string rather than object because it hasn't been declared yet in the file + author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True) + + summary = models.TextField(max_length=1000, help_text='Enter a brief description of the book') + isbn = models.CharField('ISBN', max_length=13, help_text='13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>') + + # ManyToManyField used because genre can contain many books. Books can cover many genres. + # Genre class has already been defined so we can specify the object above. + genre = models.ManyToManyField(Genre, help_text='Select a genre for this book') + + def __str__(self): + """String for representing the Model object.""" + return self.title + + def get_absolute_url(self): + """Returns the url to access a detail record for this book.""" + return reverse('book-detail', args=[str(self.id)]) +</pre> + +<p>Genre è un campo <code>ManyToManyField</code>, in modo che un libro possa avere più generi e un genere possa avere molti libri. L'autore è dichiarato come <code>ForeignKey</code>, quindi ogni libro avrà un solo autore, ma un autore può avere molti libri (in pratica un libro potrebbe avere più autori, ma non in questa implementazione semplificata!)</p> + +<p>In entrambi i tipi di campo, la classe del modello correlata viene dichiarata come il primo parametro senza nome utilizzando la classe del modello o una stringa contenente il nome del modello correlato. È necessario utilizzare il nome del modello come stringa se la classe associata non è stata ancora definita in questo file prima che venga referenziata! Gli altri parametri di interesse nel campo <code>author</code> sono <code>null=True,</code> che consente al database di memorizzare un valore <code>Null</code> se nessun autore viene selezionato e <code>on_delete=models.SET_NULL</code>, che imposterà il valore dell'autore su <code>Null</code> se l'autore associato al record viene cancellato.</p> + +<p>Inoltre il modello definisce <code>__str__()</code> , utilizzando il titolo del libro <code>title</code> per rappresentare un record di <code>Book</code>. L'ultimo metodo, <code>get_absolute_url()</code> ritorna un URL che può essere usato per accedere a un record di dettaglio per questo modello (per farlo funzionare dovremo definire una mappatura URL che abbia il nome <code>book-detail</code>, e una view e un template associati).</p> + +<h3 id="Modello_BookInstance">Modello BookInstance</h3> + +<p>Copia il modello <code>BookInstance</code> sotto gli altri modelli. <code>BookInstance</code> rappresenta una copia specifica di un libro che potrebbe essere presa in prestito da qualcuno e include informazioni sul fatto che la copia sia disponibile o sulla data in cui è prevista la restituzione, o dettagli sulla versione e un ID univoco per il libro nella biblioteca.</p> + +<p>Alcuni metodi e campi suoneranno familiari. Il modello utilizza</p> + +<ul> + <li><code>ForeignKey</code> per identificare il <code>Book</code> (ogni book ha possibilità di avere molte copie, ma una copia può avere un solo <code>Book</code>).</li> + <li><code>CharField</code> per rappresentare l'edizione del libro.</li> +</ul> + +<pre class="brush: python">import uuid # Required for unique book instances + +class BookInstance(models.Model): + """Model representing a specific copy of a book (i.e. that can be borrowed from the library).""" + id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular book across whole library') + book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True) + imprint = models.CharField(max_length=200) + due_back = models.DateField(null=True, blank=True) + + LOAN_STATUS = ( + ('m', 'Maintenance'), + ('o', 'On loan'), + ('a', 'Available'), + ('r', 'Reserved'), + ) + + status = models.CharField( + max_length=1, + choices=LOAN_STATUS, + blank=True, + default='m', + help_text='Book availability', + ) + + class Meta: + ordering = ['due_back'] + + def __str__(self): + """String for representing the Model object.""" + return f'{self.id} ({self.book.title})'</pre> + +<p>Dichiaramo una ulteriore serie di nuovi campi di altri tipi:</p> + +<ul> + <li><code>UUIDField</code> usato per l'<code>id</code> per impostarlo come <code>primary_key</code> per questo modello. Questo tipo di campo alloca un valore globalmente univoco per ogni istanza (una per ogni libro che è possibile trovare nella biblioteca).</li> + <li><code>DateField</code> usato per la data <code>due_back</code> (data in cui il libro dovrebbe ritornare disponibile dopo essere stato in prestito o in manutenzione). Questo valore può essere <code>blank</code> o <code>null</code> (necessario per quando il libro è disponibile). Il metadato del modello (<code>Class Meta</code>) utilizza questo campo per ordinare i record quando vengono restituiti da una query.</li> + <li><code>status</code> è un <code>CharField</code> che definisce una scelta/lista di selezione. Come puoi vedere, definiamo una tupla contenente tuple di coppie chiave-valore (<strong>LOAN_STATUS</strong>) e la passiamo all'argomento di <strong>choices</strong>. Il valore in una coppia chiave/valore è un valore di visualizzazione che un utente può selezionare, mentre le chiavi sono i valori che vengono effettivamente salvati se l'opzione è selezionata. Abbiamo anche impostato un valore predefinito di "m" (<em>manutenzione</em>) poiché i libri inizialmente non saranno disponibili prima di essere immagazzinati sugli scaffali.</li> +</ul> + +<p><code>__str__()</code> rappresenta l'oggetto <code>BookInstance</code> usando una combinazione del suo id univoco e del titolo del libro.</p> + +<div class="note"> +<p><strong>Nota</strong>: un po' di Python:</p> + +<ul> + <li>A partire da Python 3.6, puoi utilizzare la sintassi di interpolazione delle stringhe (anche nota come f-strings): <code>f'{self.id} ({self.book.title})'</code>.</li> + <li>in altre versioni di questo tutorial, più vecchie, usavamo una stringa formattata (<a href="https://www.python.org/dev/peps/pep-3101/">formatted string</a>), che è un altro modo valido di formattare le stringhe in Python (esempio: <code>'{0} ({1})'.format(self.id,self.book.title)</code>).</li> +</ul> +</div> + +<h3 id="Modello_Autore">Modello Autore</h3> + +<p>Copia il modello <code>Author</code> (che trovi qui sotto) dopo il codice esistente in <strong>models.py</strong>.</p> + +<pre class="brush: python">class Author(models.Model): + """Model representing an author.""" + first_name = models.CharField(max_length=100) + last_name = models.CharField(max_length=100) + date_of_birth = models.DateField(null=True, blank=True) + date_of_death = models.DateField('Died', null=True, blank=True) + + class Meta: + ordering = ['last_name', 'first_name'] + + def get_absolute_url(self): + """Returns the url to access a particular author instance.""" + return reverse('author-detail', args=[str(self.id)]) + + def __str__(self): + """String for representing the Model object.""" + return f'{self.last_name}, {self.first_name}' + +</pre> + +<p>Tutti i campi/metodi dovrebbero ora essere familiari. Il modello definisce un autore avente un nome, un cognome, una data di nascita e la data di morte (entrambe opzionali). Esso specifica che per impostazione predefinita <code>__str__()</code> restituisca il nome nell'ordine <em>cognome</em> <em>nome</em>. Il metodo <code>get_absolute_url()</code> inverte il mapping degli URL di <code>author-detail</code> per ottenere l'URL per la visualizzazione di un singolo autore.</p> + +<h2 id="Rieseguire_le_migrazioni_del_database">Rieseguire le migrazioni del database</h2> + +<p>Tutti i modelli sono stati creati. Rilanciamo la migrazione del database per aggiungerli effettivamente al database.</p> + +<pre><code>python3 manage.py makemigrations +python3 manage.py migrate</code></pre> + +<h2 id="Modello_del_linguaggio_—_Sfida">Modello del linguaggio — Sfida</h2> + +<p>Immagina che un benefattore locale doni un certo numero di nuovi libri scritti in un'altra lingua (diciamo, Farsi). La sfida è capire come questi sarebbero meglio rappresentati nel nostro sito web della biblioteca e poi aggiungerli ai model.</p> + +<p>Alcune considerazioni:</p> + +<ul> + <li>"Language" dovrebbe essere associato con <code>Book</code>, <code>BookInstance</code>, o altri objects?</li> + <li>I diversi linguaggi dovrebbero essere rappresentati utilizzando un model, una casella di testo o una lista codificata a mano?</li> +</ul> + +<p>Dopo aver deciso, aggiungi il campo. Puoi vedere cosa abbiamo deciso su Github <a href="https://github.com/mdn/django-locallibrary-tutorial/blob/master/catalog/models.py">here</a>.</p> + +<p>Non dimenticare di rieffettuare le migrazioni dopo ogni cambiamento al tuo modello.</p> + +<pre><code>python3 manage.py makemigrations</code><code> +python3 manage.py migrate</code></pre> + +<ul> +</ul> + +<ul> +</ul> + +<h2 id="Sommario">Sommario</h2> + +<p>In questo articolo abbiamo appreso come sono definiti i modelli, quindi abbiamo utilizzato queste informazioni per progettare e implementare modelli appropriati per il sito Web LocalLibrary.</p> + +<p>A questo punto ci allontaneremo brevemente dalla creazione del sito e controlleremo il sito di amministrazione di Django. Questo sito ci permetterà di aggiungere alcuni dati alla biblioteca, che possiamo quindi visualizzare usando le nostre view e template (ancora da creare).</p> + +<h2 id="Consulta_anche">Consulta anche</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/intro/tutorial02/">Writing your first Django app, part 2</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/db/queries/">Making queries</a> (Django Docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/querysets/">QuerySet API Reference</a> (Django Docs)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django")}}</p> + +<h2 id="In_questo_modulo">In questo modulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> diff --git a/files/it/learn/server-side/django/sessions/index.html b/files/it/learn/server-side/django/sessions/index.html new file mode 100644 index 0000000000..0706090bd5 --- /dev/null +++ b/files/it/learn/server-side/django/sessions/index.html @@ -0,0 +1,195 @@ +--- +title: 'Django Tutorial Part 7: Sessions framework' +slug: Learn/Server-side/Django/Sessions +tags: + - Articolo + - Principiante + - Python + - Server + - django + - sessioni +translation_of: Learn/Server-side/Django/Sessions +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django")}}</div> + +<p class="summary">Questo tutorial estende il nostro sito <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>, aggiungendo un contatore di visite session-based alla home page. Questo è un esempio relativamente semplice, ma mostra come si può usare il session framework per fornire comportamento persistente per utenti anonimi nei tuoi siti.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td>Completa tutti gli argomenti dei tutorial precedenti, compreso <a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></td> + </tr> + <tr> + <th scope="row">Obiettivo:</th> + <td>Capire come vengono utilizzate le sessioni.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica">Panoramica</h2> + +<p>Il sito <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a> che abbiamo creato nei precedenti tutorial permette agli utenti di navigare tra i libri e gli autori nel catalogo. Anche se il contenuto viene generato dinamicamente dal database, ogni utente essenzialmente avrà accesso alle stesse pagine e e gli stessi tipi di informazione quando utilizzano il sito.</p> + +<p>In una biblioteca "reale" potresti desiderare di fornire agli utenti individuali una esperienza customizzata, basata sul loro precedente utilizzo del sito, preferenze, ecc. Per esempio, potresti nascondere messaggi di avviso di cui gli utenti hanno già preso conoscenza la prossima volta che essi visitano il sito, o archiviare e rispettare le loro preferenze (ad esempio, il numero di risultati di ricerca che vogliono mostrato su ogni pagina). </p> + +<p>Il session framework ti consente di implementare questo tipo di comportamento, permettendoti di memorizzare e recuperare dati arbitrari su una base di visitstore per sito (per-site-visitor). </p> + +<h2 id="Cosa_sono_le_sessioni">Cosa sono le sessioni?</h2> + +<p>Tutte le comunicazioni tra browser web e i server avvengono attraverso il prootocollo HTTP, che è <em>stateless</em>. Il fatto che il protocollo sia stateless significa che i messagggi tra il client e il server sono completamente indipendenti da ciascuno degli altri— non esiste la nozione di "sequenza" o comportamento basato sui precedenti messaggi. Di conseguenza, se vuoi avere un sito che tenga traccia delle relazioni che sono in attive con un client, hai bisogno di implementarlo tu stesso.</p> + +<p>Le sessioni sono il meccanismo utilizzato da Django (e dalla maggior parte dell'Internet) per tenere traccia dello "stato" tra il sito e un particolare browser. Le sessioni ti consentono di memorizzare dati arbitrari per browser, e avere questi dati disponibili per il sito ogni volta che il browser si connette. Item individuali di dati associati con la sessione sono quindi referenziati con una "key", la quale è utilizzata sia per rchiviare che per recuperare i dati.</p> + +<p>Django utilizza un cookie contenente uno speciale <em>session id</em> per identificare ciascun browser e la sua sessione associata col sito. I <em>dati</em> della sessione effettiva sono archiviati nel database del sito di default (questo è più sicuro del memorizzare i dati in un cookie, dove sono più vulnerabili a utenti malevoli). Si può configurare Django per memorizzare i dati della sessione in altre posizioni (nella cache, nei file, nei "secure" cookie), ma la posizione di default è una opzione buona e relativamente sicura.</p> + +<h2 id="Abilitare_le_sessioni">Abilitare le sessioni</h2> + +<p>Le sessioni sono state abilitate automaticamente quando abbiamo <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">creato lo scheletro del sito web</a> (nel tutorial 2).</p> + +<p>La configurazione è imnpostata nelle sezioni <code>INSTALLED_APPS</code> e <code>MIDDLEWARE</code> del file di progetto (<strong>locallibrary/locallibrary/settings.py</strong>), come mostrato qui sotto:</p> + +<pre class="brush: python">INSTALLED_APPS = [ + ... +<strong> 'django.contrib.sessions',</strong> + .... + +MIDDLEWARE = [ + ... +<strong> 'django.contrib.sessions.middleware.SessionMiddleware',</strong> + ....</pre> + +<h2 id="Utilizzo_delle_sessioni">Utilizzo delle sessioni</h2> + +<p>Si può accedere all'attributo <code>session</code> nell view dal parametro <code>request</code> (una <code>HttpRequest</code> passata dentro come primo argomento alla view). Questo attributo sessione rappresenta la connessione specifica con l'utente attuale (o per essere più precisi, la connessione al browser attuale, come identificato dal session id nel cookie del browser per questo sito).</p> + +<p>L'attributo <code>session</code> è un oggetto simile a un dizionario (dictionary-like) che puoi leggere e scrivere quante volte vuoi nella tua view, modificandolo come desiderato. Si possono effettuare tutte le normali operazioni dei dictionary, inclusa la cancellazione di tutti i dati, testare se una chiave è presente, ciclare sui dati, ecc. Il più delle volte userete solo l'API standard "dictionary" per ottenere valori e impostare valori.</p> + +<p>I frammenti di codice sotto mostrano come si può ottenere, impostare, e cancellare alcuni dati con la key "<code>my_car</code>", associata alla sessione corrente (browser). </p> + +<div class="note"> +<p><strong>Nota</strong>: Una delle cose belle di Django è che non c'è bisogno di pensare ai meccanismi che legano la sessione alla tua attuale richiesta nella tua view. Se dovessimo usare i frammenti di codice qui sotto nella nostra view, sapremmo che l'informazione su <code>my_car</code> è associata solo al browser che ha inviato la richiesta corrente.</p> +</div> + +<pre class="brush: python"># Get a session value by its key (e.g. 'my_car'), raising a KeyError if the key is not present +my_car = request.session['my_car'] + +# Get a session value, setting a default if it is not present ('mini') +my_car = request.session.get('my_car', 'mini') + +# Set a session value +request.session['my_car'] = 'mini' + +# Delete a session value +del request.session['my_car'] +</pre> + +<p>L'API offre anche un certo numero di altri metodi che sono usati principalmente per gestire il cookie associato alla sessione. Per esampio, ci sono metodi per testare che i cookie sono supportati nel browser client, per impostare e controllare la data di scadenza del cookie, e per cancellare le sessioni scadute dal data store. Puoi trovare informazioni sulla API completa in <a href="https://docs.djangoproject.com/en/2.1/topics/http/sessions/">How to use sessions</a> (Django docs).</p> + +<h2 id="Salvare_i_dati_di_sessione">Salvare i dati di sessione</h2> + +<p>Di default, Django salva solamente il database di sessione e invia il session cookie al client quando la sessione è stata <em>modificata</em> (assegnata) o<em>cancellata</em>. Se si sta aggiornando qualche dato utilizzando la sua session key come mostrato nella precedente sezione, allora non devi preoccuparti di questo! Per esempio:</p> + +<pre class="brush: python"># This is detected as an update to the session, so session data is saved. +request.session['my_car'] = 'mini'</pre> + +<p>Se si stanno aggiornando alcune informazioni <em>all'interno</em> dei dati di sessione, allora Django non riconoscerà che hai fatto una modifica alla sessione e salva i dati (per esempio, se dovessi modificare i dati "<code>wheels</code>" all'interno dei tuoi dati "<code>my_car</code>", come mostrato sotto). In questo caso avrai bisogno di contrassegnare esplicitamente la sessione come modificata.</p> + +<pre class="brush: python"># Session object not directly modified, only data within the session. Session changes not saved! +request.session['my_car']['wheels'] = 'alloy' + +# Set session as modified to force data updates/cookie to be saved. +<code>request.session.modified = True</code> +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Si può modificare il comportamento in modo che il sito aggiorni il database/invii cookie su ciascuna request aggiungendo <code>SESSION_SAVE_EVERY_REQUEST = True</code> nelle tue impostazioni di progetto (<strong>locallibrary/locallibrary/settings.py</strong>).</p> +</div> + +<h2 id="Semplice_esempio_—_ottenere_il_conteggio_delle_visite">Semplice esempio — ottenere il conteggio delle visite</h2> + +<p>Come esempio semplice del mondio reale, aggiorneremo la nostra biblioteca per dire all'utente attuale quante volte essi hanno visitato la home page della <em>LocalLibrary</em>. </p> + +<p>Apri <strong>/locallibrary/catalog/views.py</strong>, e effettua le modifiche mostrate in grassetto sotto. </p> + +<pre class="brush: python">def index(request): + ... + + num_authors = Author.objects.count() # The 'all()' is implied by default. + +<strong> # Number of visits to this view, as counted in the session variable. + num_visits = request.session.get('num_visits', 0) + request.session['num_visits'] = num_visits + 1</strong> + +<strong> context = { + 'num_books': num_books, + 'num_instances': num_instances, + 'num_instances_available': num_instances_available, + 'num_authors': num_authors, + 'num_visits': num_visits, + }</strong> + + # Render the HTML template index.html with the data in the context variable. + return render(request, 'index.html', context=context)</pre> + +<p>Qui prima otteniamo il valore della session key <code>'num_visits'</code>, impostiamo il valore a 0 se esso non è stato precedentemente impostato. Ogni volta che viene ricevuta una richiesta, allora si incrementa il valore e lo si memorizza di nuovo nella sessione (per la prossima volta che l'utente visita la pagina). La variabile <code>num_visits</code> viene quindi passata al template nella nostra variabile context.</p> + +<div class="note"> +<p><strong>Nota</strong>: Potremmo anche verificare se i cookie sono anche supportati nel browser qui (vedi <a href="https://docs.djangoproject.com/en/2.1/topics/http/sessions/">How to use sessions</a> per esempi) o progettare la nostra UI in modo che non importa se i cookie sono supportati o meno.</p> +</div> + +<p>Aggiungi la linea che trovi alla fine del blocco qui sotto al tuo template HTML principale (<strong>/locallibrary/catalog/templates/index.html</strong>) alla fine della sezione "Dynamic content" per mostrare la variabile context:</p> + +<pre class="brush: html"><h2>Dynamic content</h2> + +<p>The library has the following record counts:</p> +<ul> + <li><strong>Books:</strong> \{{ num_books }}</li> + <li><strong>Copies:</strong> \{{ num_instances }}</li> + <li><strong>Copies available:</strong> \{{ num_instances_available }}</li> + <li><strong>Authors:</strong> \{{ num_authors }}</li> +</ul> + +<strong><p>You have visited this page \{{ num_visits }}{% if num_visits == 1 %} time{% else %} times{% endif %}.</p></strong> +</pre> + +<p>Salva le modifiche e riavvia il server di test. Ogni volta che tu farai un refresh della pagina, il numero dovrebbe aggiornarsi.</p> + +<ul> +</ul> + +<h2 id="Riepilogo">Riepilogo</h2> + +<p>Ora sai come è facile utilizzare per migliorare la tua interazione con utenti <em>anonimi</em>. </p> + +<p>Nei nostri prossimi articoli spiegheremo il framework per l'autenticazione ed autorizzazione (permessi), e ti mostreremo come supportare gli account user.</p> + +<h2 id="Vedi_anche">Vedi anche</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.1/topics/http/sessions/">How to use sessions</a> (Django docs)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/Authentication", "Learn/Server-side/Django")}}</p> + +<h2 id="In_questo_modulo">In questo modulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> diff --git a/files/it/learn/server-side/django/skeleton_website/index.html b/files/it/learn/server-side/django/skeleton_website/index.html new file mode 100644 index 0000000000..1f5d7117ff --- /dev/null +++ b/files/it/learn/server-side/django/skeleton_website/index.html @@ -0,0 +1,406 @@ +--- +title: 'Django Tutorial Parte 2: Creare lo scheletro di un sito web' +slug: Learn/Server-side/Django/skeleton_website +tags: + - Articolo + - Guida + - Intro + - Introduzione + - Principianti + - Tutorial + - backend + - django + - imparare +translation_of: Learn/Server-side/Django/skeleton_website +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django/Models", "Learn/Server-side/Django")}}</div> + +<p class="summary">Questo secondo articolo del nostro <a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial Django</a> mostra come creare uno "scheletro" di progetto di un sito web come base, che potrà poi essere popolato con le impostazioni specifiche del sito, con i path, con i modelli, le view, e i template.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Creare un ambiente di sviluppo Django</a>. Visita: <a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial</a>.</td> + </tr> + <tr> + <th scope="row">Obiettivi:</th> + <td>Essere in grado di utilizzare i tool Django per iniziare il tuo progetto web.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica">Panoramica</h2> + +<p>Questo articolo mostra come creare uno "scheletro" di un sito web, che potrà poi essere popolato con impostazioni specifiche del sito, con i path, con i model, le view, e i template (discuteremo di questo in successivi articoli).</p> + +<p>Il processo è semplice:</p> + +<ol> + <li>Utilizzare lo strumento <code>django-admin</code> per creare la cartella del progetto, i templates di file di base e lo script di gestione del progetto (<strong>manage.py</strong>).</li> + <li>Utilizzare <strong>manage.py</strong> per creare una o più <em>applicazioni</em><span style="line-height: 1.5;">.</span> + <div class="note"> + <p><strong>Nota</strong>: un sito Web può essere costituito da una o più sezioni, ad es. sito principale, blog, wiki, area download, ecc. Django ti incoraggia a sviluppare questi componenti come <em>applicazioni</em> separate, che potrebbero poi essere riutilizzate in diversi progetti, se necessario. </p> + </div> + </li> + <li>Registrare le nuove applicazioni per includerle nel progetto<span style="line-height: 1.5;">. </span></li> + <li>Collegare il mapper url/path per ciascuna applicazione<span style="line-height: 1.5;">.</span></li> +</ol> + +<p>Per il <a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">sito web Local Library</a> la cartella del sito web e la sua cartella di progetto saranno chiamate <em>locallibrary</em>, e avremo solo un'applicazione chiamata <em>catalog</em>. La struttura delle cartelle di livello superiore sarà quindi la seguente:</p> + +<pre class="brush: bash"><code>locallibrary/ # Cartella Sito Web + manage.py # Script per eseguire i tool di Django per questo progetto (creato utilizzando django-admin) + locallibrary/ # Cartella sito web/progetto (creata utilizzando django-admin) + catalog/ # Cartella Application (creata utilizzando manage.py)</code> +</pre> + +<p>Le sezioni seguenti illustrano in dettaglio le fasi del processo e mostrano come testare le modifiche. Alla fine dell'articolo discuteremo alcune delle altre configurazioni a livello di sito che potresti fare anche in questa fase.</p> + +<h2 id="Creare_il_progetto">Creare il progetto</h2> + +<p>Per prima cosa apri un prompt dei comandi / terminale, assicurati di essere nel tuo <a href="/en-US/docs/Learn/Server-side/Django/development_environment#Using_a_virtual_environment">virtual environment</a>, accedi a dove vuoi archiviare le tue app Django (mettile in un posto facilmente reperibile, all'interno della tua cartella documenti) e crea una cartella per il tuo nuovo sito web (in questo caso: <em>django_projects</em>). Poi entra nella cartella col comando cd:</p> + +<pre class="brush: bash">mkdir django_projects +cd django_projects</pre> + +<p>Crea il nuovo progetto utilizzando il comando <code>django-admin startproject</code> come mostrato, poi naviga fino alla cartella.</p> + +<pre class="brush: bash">django-admin startproject locallibrary +cd locallibrary</pre> + +<p>lo strumento <code>django-admin</code> crea una struttura cartella/file come mostrata sotto:</p> + +<pre class="brush: bash"><em>locallibrary/</em> + manage.py + <em>locallibrary/</em> + __init__.py + settings.py + urls.py + wsgi.py</pre> + +<p>la cartella corrente dovrebbe somigliare alla seguente:</p> + +<pre class="syntaxbox">../django_projects/locallibrary/</pre> + +<p>La sottocartella del progetto <em>locallibrary</em> è l'entry point per il sito Web:</p> + +<ul> + <li><strong>__init__.py è</strong> un file vuoto che indica a Python di trattare questa directory come un pacchetto Python.</li> + <li><strong>settings.py</strong> contiene tutte le impostazioni del sito web. Qui è dove registriamo tutte le applicazioni che creiamo, la posizione dei nostri file statici, i dettagli di configurazione del database, ecc.</li> + <li><strong>urls.py</strong> definisce i mapping url-to-view del sito. Mentre questo potrebbe contenere tutto il codice di mappatura dell'URL, è più comune delegare parte della mappatura a particolari applicazioni, come vedremo più avanti.<span style="line-height: 1.5;"> </span></li> + <li><strong style="line-height: 1.5;">wsgi.py</strong><span style="line-height: 1.5;"> </span>è usato per aiutare la tua applicazione Django a comunicare con il server web.</li> +</ul> + +<p>Lo script <strong>manage.py</strong> viene utilizzato per creare applicazioni, lavorare con i database e avviare il server web di sviluppo. </p> + +<h2 id="Creare_l'applicazione_di_catalogo">Creare l'applicazione di catalogo</h2> + +<p>Quindi, esegui il seguente comando per creare l'applicazione <em>catalog</em> che risiederà all'interno del nostro progetto di localibrary (deve essere eseguito nella stessa cartella di manage.py del tuo progetto):</p> + +<pre class="brush: bash">python3 manage.py startapp catalog</pre> + +<div class="note"> +<p><strong>Note</strong>: il comando precedente è per Linux / macOS X. Su Windows il comando dovrebbe essere:</p> + +<p> <code>py -3 manage.py startapp catalog</code></p> + +<p>Se stai lavorando con Windows rimpiazza <code>python3</code> con <code>py -3</code> in tutto questo modulo.</p> + +<p>Se stai usando la versione di Python 3.7.0 o superiore, devi usare solo:</p> + +<p><code>py manage.py startapp catalog</code></p> +</div> + +<p>Lo strumento crea una nuova cartella e la popola con i file per le diverse parti dell'applicazione (mostrate in grassetto sotto). La maggior parte dei file ha un nome utile in base al loro scopo (ad esempio, le viste dovrebbero essere memorizzate in <strong>views.py</strong>, models in <strong>models.py</strong>, i test <strong>tests.py</strong>, le configurazioni per l'amministrazione in <strong>admin.py</strong>, le applicazioni in <strong>apps.py</strong>) e contenere un minimo di codice per il lavoro con gli oggetti associati.</p> + +<p>La directory del progetto aggiornata dovrebbe essere così ora:</p> + +<pre class="brush: bash"><em>locallibrary/</em> + manage.py + <em>locallibrary/ +</em><strong> <em>catalog/</em> + admin.py + apps.py + models.py + tests.py + views.py + __init__.py + <em>migrations/</em></strong> +</pre> + +<p>Inoltre abbiamo:</p> + +<ul> + <li>Una cartella <em>migrations</em>, usata per memorizzare le "migrazioni" — file che ti permettono di aggiornare automaticamente il tuo database mentre modifichi i tuoi models.</li> + <li><strong>__init__.py</strong> — un file vuoto creato qui in modo che Django / Python riconoscerà la cartella come un file <a href="https://docs.python.org/3/tutorial/modules.html#packages">Python Package</a> e ti permette di usare i suoi oggetti all'interno di altre parti del progetto.</li> +</ul> + +<div class="note"> +<p><strong>Note</strong>: Hai notato cosa manca nella lista dei file sopra? Mentre c'è un posto per le tue viste e modelli, non c'è nessun posto per te per mettere i tuoi mapping url, templates e file statici. Ti mostreremo come crearli più avanti (non sono necessari in tutti i siti Web ma sono necessari in questo esempio).</p> +</div> + +<h2 id="Registrare_l'applicazione_catalog">Registrare l'applicazione catalog</h2> + +<p>Ora che l'applicazione è stata creata, dobbiamo registrarla nel progetto in modo che venga inclusa quando vengono eseguiti tutti gli strumenti (ad esempio per aggiungere modelli al database). Le applicazioni vengono registrate aggiungendole alla lista <code>INSTALLED_APPS</code> in project settings. </p> + +<p>Aprire il file di project settings <strong>django_projects/locallibrary/locallibrary/settings.py</strong> e cerca la definizione della lista <code>INSTALLED_APPS</code>. Quindi aggiungi una nuova riga alla fine dell'elenco, come mostrato in grassetto sotto.</p> + +<pre class="brush: bash">INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', +<strong> 'catalog.apps.CatalogConfig', </strong> +]</pre> + +<p>La nuova riga specifica l'oggetto di configurazione dell'applicazione (<code>CatalogConfig</code>) che è stato generato per te in <strong>/locallibrary/catalog/apps.py</strong> quando hai creato l'applicazione.</p> + +<div class="note"> +<p><strong>Nota</strong>: Noterai che ci sono già molti altri INSTALLED_APPS (e MIDDLEWARE, più in basso nel file delle impostazioni).. Questi abilitano il supporto per il <a href="/en-US/docs/Learn/Server-side/Django/Admin_site">sito Django administration</a> e, di conseguenza, molte delle funzionalità che utilizza (incluse sessioni, autenticazione, ecc.).</p> +</div> + +<h2 id="Specificare_il_database">Specificare il database</h2> + +<p>Questo è anche il punto in cui normalmente si specifica il database da utilizzare per il progetto - è logico utilizzare lo stesso database per lo sviluppo e la produzione laddove possibile, al fine di evitare piccole differenze di comportamento. Per le differenti opzioni si rimanda a <a href="https://docs.djangoproject.com/en/2.0/ref/settings/#databases">Databases</a> (Django docs). </p> + +<p>Useremo il database SQLite per questo esempio, perché non ci aspettiamo di richiedere molti accessi simultanei su un database dimostrativo, e anche perché non richiede lavoro aggiuntivo per impostarlo! Puoi vedere come è configurato questo database in <strong>settings.py</strong> (ulteriori informazioni sono incluse anche di seguito):</p> + +<pre class="brush: python">DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} +</pre> + +<p>Poichè usiamo SQLite, non abbiamo bisogno di altri setup. Andiamo avanti!</p> + +<h2 id="Altre_impostazioni_per_il_progetto">Altre impostazioni per il progetto</h2> + +<p>Il file <strong>settings.py</strong> viene anche usato per configurare un certo numero di altre impostazioni, ma a questo punto probabilmente si desidera solo modificare <a href="https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-TIME_ZONE">TIME_ZONE</a> — che dovrebbe essere impostato uguale ad una delle stringhe standard presenti nella lista <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">List of tz database time zones</a> (la colonna TZ contiene i valori da sostituire). Cambia la tua <code>TIME_ZONE</code> con una di queste stringhe, per esempio:</p> + +<pre class="brush: python">TIME_ZONE = 'Europe/Rome'</pre> + +<p>Queste altre due impostazioni invece non le cambierai ora, ma dovresti comunque conoscerle:</p> + +<ul> + <li><code>SECRET_KEY</code>. Questa è una chiave segreta utilizzata come parte della strategia di sicurezza del sito web di Django. Se non stai proteggendo questo codice in fase di sviluppo, dovrai utilizzare un codice diverso (magari letto da una variabile o file di ambiente) quando lo metti in produzione.</li> + <li><code>DEBUG</code>. Consente di visualizzare i log di debug in caso di errore, piuttosto che le risposte del codice di stato HTTP. Questo dovrebbe essere impostato su <code>False</code> in produzione in quanto le informazioni di debug sono utili per gli aggressori, ma per ora possiamo tenerlo impostato su <code>True</code>.</li> +</ul> + +<h2 id="Collegare_il_mapper_URL">Collegare il mapper URL</h2> + +<p>Il sito Web viene creato con un file di mappatura URL (<strong>urls.py</strong>) nella cartella del progetto. Sebbene sia possibile utilizzare questo file per gestire tutti i mapping degli URL, è più frequente rinviare i mapping all'applicazione associata.</p> + +<p>Aprite <strong>locallibrary/locallibrary/urls.py,</strong> notare il testo istruttivo che spiega alcuni modi per utilizzare il mappatore URL.</p> + +<pre class="brush: python">"""locallibrary URL Configuration + + +L'elenco "urlpatterns" indirizza gli URL alle viste. Per maggiori informazioni vedi: + https://docs.djangoproject.com/en/2.1/topics/http/urls/ +Esempi: +Views basate su funzioni + 1. Aggiungere un import: from my_app import views + 2. Aggiungere un URL a urlpatterns: path('', views.home, name='home') +Views basate su classi + 1. Aggiungere un import: from other_app.views import Home + 2. Aggiungere un URL a urlpatterns: path('', Home.as_view(), name='home') +Includere un altro URLconf + 1. Importare la funzione include(): from django.urls import include, path + 2. Aggiungere URL a urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path('admin/', admin.site.urls), +] +</pre> + +<p>Le mappature URL sono gestite tramite la variabile <code>urlpatterns</code>, che è una <em>list</em> Python di funzioni <code>path()</code>. Ogni funzione <code>path()</code> associa un pattern URL a una <em>view specifica</em>, che verrà visualizzata quando il pattern viene matchato, o con un altro elenco di codice di test pattern URL (in questo secondo caso, il pattern diventa "base URL" per i pattern definiti nel modulo target). La <em>list</em> <code>urlpatterns</code> definisce inizialmente una singola funzione che associa tutti gli URL con il pattern <em>admin/</em> al modulo <code>admin.site.urls</code>, che contiene le definizioni di mappatura URL proprie dell'applicazione di Amministrazione.</p> + +<div class="note"> +<p><strong>Nota</strong>: il percorso (route) in <code>path()</code> è una stringa che definisce un pattern URL da matchare. Questa stringa potrebbe includere una variabile con nome (tra parentesi angolari), ad es. <code>'catalog/<id>/'</code>. Questo pattern corrisponderà a un URL come<strong> <code>/catalog/</code></strong><code>any_chars<strong>/</strong></code> e passerà <em>any_chars </em>alla view come una stringa con nome di parametro<em><strong> </strong></em><code>id</code>. Discuteremo ulteriormente i metodi path e i route patterns in successivi argomenti.</p> +</div> + +<p>Aggiungi le linee qua sotto alla fine del file per aggiungere un nuovo elemento alla lista <code>urlpatterns</code>. Questo nuovo elemento della lista include un <code>path()</code> che inoltra richieste con il pattern <code>catalog/</code> al modulo <code>catalog.urls</code> (il file con il relativo URL <strong>/catalog/urls.py</strong>).</p> + +<pre class="brush: python"># Use include() to add paths from the catalog application +from django.urls import include +from django.urls import path + +urlpatterns += [ + path('catalog/', include('catalog.urls')), +] + +</pre> + +<p>Adesso reindirizziamo il root URL del nostro sito (cioè <code>127.0.0.1:8000</code>) all'URL <code>127.0.0.1:8000/catalog/</code>; questa è l'unica app che useremo in questo progetto. Per fare ciò, useremo una speciale funzione (<code>RedirectView</code>), che prende come primo argomento il nuovo URL relativo verso cui fare il redirect (<code>/catalog/</code>) quando il pattern URL specificato nella funzione <code>path()</code> viene matchato (il root URL, in questo caso).</p> + +<p>Aggiungere le seguenti linee di codice, sempre alla fine del file:</p> + +<pre class="brush: python">#Add URL maps to redirect the base URL to our application +from django.views.generic import RedirectView +urlpatterns += [ + path('', RedirectView.as_view(url='/catalog/', permanent=True)), +] +</pre> + +<p>Lasciare il primo parametro della funzione path vuoto per implicare '/'. Se scrivi il primo parametro come '/' Django ti darà il seguente avviso quando avvii il server di sviluppo:</p> + +<pre class="brush: python">System check identified some issues: + +WARNINGS: +?: (urls.W002) Your URL pattern '/' has a route beginning with a '/'. +Remove this slash as it is unnecessary. +If this pattern is targeted in an include(), ensure the include() pattern has a trailing '/'. +</pre> + +<p>Django non utilizza file statici come CSS, JavaScript e immagini per impostazione predefinita, ma può essere utile per lo sviluppo del server Web durante la creazione del sito. Come aggiunta finale a questo mapper URL, è possibile abilitare la pubblicazione di file statici durante lo sviluppo aggiungendo le seguenti righe.</p> + +<p>Aggiungi il seguente blocco di codice alla fine del file:</p> + +<pre><code># Use static() to add url mapping to serve static files during development (only) +from django.conf import settings +from django.conf.urls.static import static + +urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)</code> +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Ci sono diversi modi per estendere la list <code>urlpatterns</code> (nel nostro esempio utiliziamo l'operatore append <code>+=</code> per separare chiaramente il codice nuovo e da quello vecchio). Avremmo potuto semplicemente includere tutto nella definizione originale della list:</p> + +<pre class="brush: python">urlpatterns = [ + path('admin/', admin.site.urls), + path('catalog/', include('catalog.urls')), + path('', RedirectView.as_view(url='/catalog/', permanent=True)), +] + <code>static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)</code> +</pre> + +<p>Inoltre, abbiamo aggiunto la linea di import (<code>from django.urls import include</code>) insieme al codice che la utilizza, ma comunemente si preferisce mettere tutti gli import all'inizio del file Python.</p> +</div> + +<p>Come ultimo passaggio, crea un file all'interno della cartella del tuo catalogo chiamato <strong>urls.py</strong> e aggiungi il testo seguente per definire gli <code>urlpatterns</code> importati (vuoti). Qui è dove aggiungeremo i nostri modelli, mentre costruiamo l'applicazione.</p> + +<pre class="brush: python">from django.urls import path +from . import views + +urlpatterns = [ + +] +</pre> + +<h2 id="Test_del_framework_del_sito_Web">Test del framework del sito Web</h2> + +<p>A questo punto abbiamo uno scheletro completo. Il sito Web in realtà non fa ancora nulla, ma vale la pena eseguirlo per assicurarsi che nessuno dei nostri cambiamenti abbia infranto nulla.</p> + +<p>Prima di farlo, dovremmo prima eseguire una <em>migrazione del database</em>. Questo aggiorna il nostro database per includere tutti i modelli nelle nostre applicazioni installate (e rimuove alcuni avvisi di build).</p> + +<h3 id="Effettuare_migrazioni_di_database">Effettuare migrazioni di database</h3> + +<p>Django utilizza un Object-Relational-Mapper (ORM) per mappare le definizioni di modello nel codice Django alla struttura dati utilizzata dal database sottostante. Quando cambiamo le definizioni dei nostri modelli, Django tiene traccia delle modifiche e può creare script di migrazione del database (in <strong>/locallibrary/catalog/migrations/</strong>) per migrare automaticamente la struttura dati sottostante nel database in modo che corrisponda al modello.</p> + +<p>Quando abbiamo creato il sito Django ha aggiunto automaticamente un numero di modelli per l'uso da parte della sezione admin del sito (che vedremo in seguito). Eseguire i seguenti comandi per definire le tabelle per tali modelli nel database (assicurarsi di essere nella directory che contiene <strong>manage.py</strong>):</p> + +<pre class="brush: bash">python3 manage.py makemigrations +python3 manage.py migrate +</pre> + +<div class="warning"> +<p><strong>Importante</strong>: Avrai bisogno di eseguire i suddetti comandi ogni volta che i tuoi modelli cambiano in modo tale da influenzare la struttura dei dati che devono essere memorizzati (inclusi sia l'aggiunta che la rimozione di interi modelli e singoli campi).</p> +</div> + +<p>Il comando <code>makemigrations</code> crea (ma non applica) le migrazioni per tutte le applicazioni installate nel progetto (puoi anche specificare il nome dell'applicazione per eseguire semplicemente una migrazione per un singolo progetto). Questo ti dà la possibilità di controllare il codice per queste migrazioni prima che vengano applicate - quando sei un esperto di Django puoi scegliere di modificarle direttamente!</p> + +<p>Il comando <code>migrate</code> applica effettivamente le migrazioni al tuo database (Django tiene traccia di quelli che sono stati aggiunti al database corrente).</p> + +<div class="note"> +<p><strong>Nota</strong>: Consulta <a href="https://docs.djangoproject.com/en/2.1/topics/migrations/">Migrations</a> (Django docs) per info aggiuntive sui comandi meno usati nelle migrazioni.</p> +</div> + +<h3 id="Testare_il_sito_web">Testare il sito web</h3> + +<p>Durante lo sviluppo è possibile testare il sito Web utilizzando il <em>server web di sviluppo</em> e quindi visualizzandolo sul browser web locale.</p> + +<div class="note"> +<p><strong>Nota</strong>: Il web server di sviluppo non è abbastanza robusto o performante per l'uso in produzione, ma è un modo molto semplice per far funzionare il tuo sito Django durante lo sviluppo per testarlo in modo rapido. Per impostazione di default il sito si troverà sul tuo computer all'indirizzo (<code>http://127.0.0.1:8000/)</code>, ma puoi anche specificare altri computer sulla tua rete su cui hostare il sito. Per ulteriori informazioni, vedere <a href="https://docs.djangoproject.com/en/2.1/ref/django-admin/#runserver">django-admin and manage.py: runserver</a> (Django docs).</p> +</div> + +<p>Eseguire il server Web di sviluppo chiamando il comando <em>runserver</em> (nella stessa directory di <strong>manage.py</strong>):</p> + +<pre class="brush: bash">python3 manage.py runserver + + Performing system checks... + + System check identified no issues (0 silenced). + August 15, 2018 - 16:11:26 + Django version 2.1, using settings 'locallibrary.settings' + Starting development server at http://127.0.0.1:8000/ + Quit the server with CTRL-BREAK. +</pre> + +<p>Una volta attivato il server, puoi vedere il sito visitando il seguente indiriizzo sul browser web locale <code>http://127.0.0.1:8000/</code>. Dovresti vedere la seguente pagina di errore:</p> + +<p><img alt="Django Debug page for Django 2.0" src="https://mdn.mozillademos.org/files/15729/django_404_debug_page.png"></p> + +<p>Non preoccuparti! Questa pagina di errore è prevista perché non abbiamo alcuna pagina/URL definita nel modulo <code>catalogs.urls</code> (a cui siamo reindirizzati quando otteniamo un URL alla radice del sito).</p> + +<div class="note"> +<p><strong>Nota</strong>: La pagina sopra mostra una grande funzionalità di Django - registrazione automatica del debug. Verrà visualizzata una schermata di errore con informazioni utili ogni volta che non è possibile trovare una pagina o qualsiasi errore viene generato dal codice. In questo caso possiamo vedere che l'URL che abbiamo fornito non corrisponde a nessuno dei nostri pattern URL (come elencato). Il logging verrà disattivato in produzione (quando mettiamo il sito sul Web), nel qual caso verrà pubblicata una pagina meno informativa ma più user-friendly.</p> +</div> + +<p>Ora sappiamo che Django sta funzionando! </p> + +<div class="note"> +<p><strong>Nota</strong>: Dovresti rieffettuare le migrazioni ogni volta che fai dei cambiamenti significativi, non richiedono molto tempo!</p> +</div> + +<h2 id="Sfida_te_stesso">Sfida te stesso</h2> + +<p>La cartella <strong>catalog/ </strong>contiene file per le views, models, e altre parti dell'applicazione. Apri questi file e studiali. </p> + +<p>Come hai visto sopra, una mappatura URL per il sito di amministrazione è già stata aggiunta nella <strong>urls.py</strong> del progetto. Passa all'area di amministrazione nel tuo browser e vedi cosa succede (puoi dedurre l'URL corretto dalla mappatura sopra).</p> + +<ul> +</ul> + +<h2 id="Sommario">Sommario</h2> + +<p>Abbiamo creato uno scheletro completo del nostro progetto web, che potremo ora popolare con urls, models, views e templates.</p> + +<p>Ora che lo scheletro per <a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Local Library website</a> è completo e funzionante, è ora di scrivere del codice per far fare al nostro sito cosa vogliamo fargli fare. </p> + +<h2 id="Consulta_anche">Consulta anche</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/2.0/intro/tutorial01/">Writing your first Django app - part 1</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/2.1/ref/applications/#configuring-applications">Applications</a> (Django Docs). Contiene informazioni su come configurare le applicazioni.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django/Models", "Learn/Server-side/Django")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li> + <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> diff --git a/files/it/learn/server-side/django/tutorial_local_library_website/index.html b/files/it/learn/server-side/django/tutorial_local_library_website/index.html new file mode 100644 index 0000000000..eeabfd4a01 --- /dev/null +++ b/files/it/learn/server-side/django/tutorial_local_library_website/index.html @@ -0,0 +1,79 @@ +--- +title: 'Django Tutorial: The Local Library website' +slug: Learn/Server-side/Django/Tutorial_local_library_website +tags: + - Articolo + - Guida + - Principiante + - Scripting + - Tutorial + - django + - imparare + - lato-server +translation_of: Learn/Server-side/Django/Tutorial_local_library_website +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django")}}</div> + +<p class="summary">Il primo articolo della serie di tutorial pratici spiega ciò che imparerai, e fornisce una panoramica del sito web di esempio "local library" con cui andremo a lavorare e che faremo evolvere nei prossimi articoli.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td>Leggere la <a href="/en-US/docs/Learn/Server-side/Django/Introduction">Introduzione a Django</a>. Per i seguenti articoli sarà anche necessario avere predisposto un <a href="/en-US/docs/Learn/Server-side/Django/development_environment"> ambiente di sviluppo Django</a>. </td> + </tr> + <tr> + <th scope="row">Obiettivo:</th> + <td>Presentare l'applicazione di esempio utilizzata in questo tutorial, e mettere in grado i lettori di capire quali argomenti saranno trattati.</td> + </tr> + </tbody> +</table> + +<h2 id="Panoramica">Panoramica</h2> + +<p>Benvenuti al tutorial Django MDN "Local Library", nel quale sviluppiamo un sito web che potrebbe essere utilizzato per gestire il catalogo per una biblioteca locale.</p> + +<p>In questa serie di articoli tutorial vedrai come:</p> + +<ul> + <li>Usare i tool di Django per creare lo scheletro di un sito web e un'applicazione.</li> + <li>Avviare e arrestare il server di sviluppo.</li> + <li>Creare models per rappresentare i dati dell'applicazione.</li> + <li>Utilizzare il sito di amministrazione Django-admin per popolare i dati del tuo sito.</li> + <li>Creare view per recuperare dati specifici in risposta a richieste diverse e template per fare il rendering dei dati come HTML da visualizzare nel browser.</li> + <li>Creare mapper per associare pattern URL diversi a view specifiche.</li> + <li>Aggiungere autorizzazione utente e sessioni per controllare il comportamento del sito e l'accesso ad esso.</li> + <li>Lavorare con i form.</li> + <li>Scrivere codice di test per la tua app.</li> + <li>Usare efficacemente la sicurezza di Django.</li> + <li>Distribuire la tua applicazione in produzione.</li> +</ul> + +<p>Hai già imparato qualcosa riguardo ad alcuni di questi argomenti e hai toccato brevemente gli altri. Alla fine della serie di tutorial dovresti sapere abbastanza per sviluppare semplici app Django da solo.</p> + +<h2 id="Il_sito_web_LocalLibrary">Il sito web LocalLibrary</h2> + +<p><em>LocalLibrary</em> è il nome di un sito web che creeremo e faremo evolvere durante il corso di questa serie di tutorial. Come ti aspetteresti, lo scopo del sito è quello di fornire un catalogo online per un piccola biblioteca locale, in cui gli utenti possono ricercare i libri disponibili e gestire i loro account.</p> + +<p>Questo esempio è stato scelto con cura poichè può essere scalato per mostrare pochi o molti dettagli di cui necessitiamo, e può essere utilizzato per mostrare quasi tutte le feature di Django. In modo più importante, ci permette di fornire un percorso <em>guidato</em> attraverso le più importanti funzionalità nel web framework Django:</p> + +<ul> + <li>Nei primi pochi articoli tutorial definiremo una semplice biblioteca <em>browse-only (solo sfogliabile)</em> che i membri della biblioteca possono utilizzare per trovare che libri sono disponibili. Questo ci permette di esplorare le operazioni che sono comuni in quasi tutti i siti web: leggere e visualizzare contenuti da un database.</li> + <li>Mentre progrediamo, l'esempio biblioteca naturalmente si estende per dimostrare feature più avanzate di Django. Per esempio possiamo estendere la biblioteca per permettere agli utenti di prenotare libri, e utilizzare ciò per dimostrare come utilizzare i form, e supportare l'autenticazione utente.</li> +</ul> + +<p>Anche se questo è un esempio molto estensibile, viene chiamato <em><strong>Local</strong>Library</em> per una ragione — stiamo sperando di mostrare le informazioni minime che possano aiutare a metterti in funzione con Django rapidamente. Di conseguenza, archivieremo informazioni su libri, copie di libri, autori e altre informazioni chiave. Non memorizzeremo tuttavia informazioni circa altri elementi che una biblioteca potrebbe archiaviare, o forniremo l'infrastruttura necessaria per supportare più siti di biblioteche o altre feature di "grandi biblioteche". </p> + +<h2 id="Sono_bloccato_dove_posso_trovare_il_sorgente">Sono bloccato, dove posso trovare il sorgente?</h2> + +<p>Man mano che so segue il tutorial forniremo i frammenti di codice appropriati da copiare e incollare in ciascun punto, e ci sarà altro codice che speriamo tu estenda da solo (con un po' di guida).</p> + +<p>Se ci si blocca, si può trovare la versione completamente sviluppata del sito web <a href="https://github.com/mdn/django-locallibrary-tutorial">su Github qui</a>.</p> + +<h2 id="Sommario">Sommario</h2> + +<p>Ora che sai un po' di più sul sito web <em>LocalLIbrary</em> e cosa stai per andare a imparare, è tempo di iniziare a creare un <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">scheletro di progetto</a> per contenere il nostro esempio.</p> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django")}}</p> diff --git a/files/it/learn/server-side/express_nodejs/index.html b/files/it/learn/server-side/express_nodejs/index.html new file mode 100644 index 0000000000..d6a55af9c8 --- /dev/null +++ b/files/it/learn/server-side/express_nodejs/index.html @@ -0,0 +1,75 @@ +--- +title: Express web framework (Node.js/JavaScript) +slug: Learn/Server-side/Express_Nodejs +tags: + - Codice + - Express + - Express.js + - Intro + - JavaScript + - Node + - Principiante + - Scripting + - Server + - node.js +translation_of: Learn/Server-side/Express_Nodejs +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">Express è un framework di tipo unopinionated, scritto in Javascript ed hostato dentro un amiente di runtime Node.js. Qusto modulo illustra i benefici chiave di questo framework, come configurare un ambiente di sviluppo, e come compiere alcuni compiti comuni di sviluppo e deploy.</p> + +<h2 id="Prerequisiti">Prerequisiti</h2> + +<p>Prima di iniziare dovrai esssere in grado di capire cosa sia la programmazione lato server e che cosa sia un framework, preferibilmente leggendo i topics <a href="/en-US/docs/Learn/Server-side/First_steps">Server-side website programming first steps</a>. Una infarinatura generale di programmazione e <a href="/en-US/docs/Web/JavaScript">JavaScript</a> è altamente raccomandata, ma non necessaria per comprendere i concetti chiave.</p> + +<div class="note"> +<p>Nota: questo sito Web offre molte risorse utili per l'apprendimento di JavaScript nel contesto dello sviluppo lato client: <a href="/en-US/docs/Web/JavaScript">JavaScript</a>, <a href="/en-US/docs/Web/JavaScript/Guide">JavaScript Guide</a>, <a href="/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics">JavaScript Basics</a>, <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>. Il linguaggio e i concetti fondamentali di JavaScript sono gli stessi per lo sviluppo lato server su Node.js e questo materiale sarà rilevante. Node.js offre API aggiuntive per supportare funzionalità utili in ambienti senza browser (es. per creare un server HTTP ed accedere al file system, ma non supporta le API per lavorare sul browser o interagire con il DOM).</p> + +<p>Questa guida fornirà alcune informazioni su come lavorare con Node.js e Express, e ci sono numerose altre eccellenti risorse su Internet e nei libri - alcune delle quali disponibili ai seguenti link <a href="http://stackoverflow.com/a/5511507/894359">How do I get started with Node.js</a> (StackOverflow) e <a href="https://www.quora.com/What-are-the-best-resources-for-learning-Node-js?">What are the best resources for learning Node.js?</a> (Quora).</p> +</div> + +<h2 id="Guide">Guide</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node: una introduzione</a></dt> + <dd>In questo primo articolo rispondiamo alle domande "Cos'è Node?" e "Cos'è Express?" e faremo una panoramica di ciò che rende speciale la struttura web Express. Descriveremo le caratteristiche principali e mostreremo alcuni dei principali elementi costitutivi di un'applicazione Express (sebbene a questo punto non avrete ancora un ambiente di sviluppo in cui testarlo).</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Creare un ambiente di sviluppo Node (Express)</a></dt> + <dd>Ora che sai a cosa serve Express, ti mostreremo come configurare e testare un ambiente di sviluppo Node/Express su Windows, Linux (Ubuntu) e Mac OS X. Qualunque sia il sistema operativo che stai usando, questo articolo dovrebbe darti quello che ti serve per iniziare a sviluppare applicazioni Express.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Tutorial Express: Il sito Local Library</a></dt> + <dd>Il primo articolo della nostra serie di tutorial pratica spiega cosa imparerai e fornirà una panoramica del sito web di esempio della "biblioteca locale" che elaboreremo e svilupperemo in articoli successivi.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Parte 2: Creare lo scheletro del sito</a></dt> + <dd>Questo articolo mostra come è possibile creare uno "scheletro" di un sito web, che può poi essere popolato con percorsi, modelli/viste e database specifici del sito.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Parte 3: Usare un Database (con Mongoose)</a></dt> + <dd>Questo articolo introduce brevemente i database per Node / Express. Poi continua a mostrare come possiamo usare <a href="http://mongoosejs.com/">Mongoose</a> per fornire l'accesso al database per il sito Web LocalLibrary. Spiega come vengono dichiarati lo schema e i modelli dell'oggetto, i tipi di campo principali e la convalida di base. Mostra anche brevemente alcuni dei principali modi in cui è possibile accedere ai dati del modello.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Parte 4: Routeing e controllers</a></dt> + <dd>In questo tutorial imposteremo i percorsi (codice di gestione degli URL) con le funzioni di gestione "fittizia" per tutti gli endpoint delle risorse che saranno necessari nel sito Web di LocalLibrary. Al termine, avremo una struttura modulare per il nostro codice di gestione del routing, che possiamo estendere con le funzioni di gestione reale nei seguenti articoli. Avremo anche una buona conoscenza di come creare percorsi modulari usando Express.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Parte 5: Mostrare i dati della libreria</a></dt> + <dd>Siamo ora pronti per aggiungere le pagine che visualizzano i libri del sito Web LocalLibrary e altri dati. Le pagine includeranno una home page che mostra quanti record abbiamo di ogni tipo di modello e lista e pagine di dettaglio per tutti i nostri modelli. Lungo la strada, acquisiremo esperienza pratica nell'ottenere record dal database e utilizzare modelli.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Utilizzare i form</a></dt> + <dd>Vedremo come lavorare con i<a href="/en-US/docs/Web/Guide/HTML/Forms"> Forms</a> in Express, usando Pug, e in particolare come creare forms per eseguire operazioni CRUD.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Parte 7: Deployare in produzion</a>e</dt> + <dd>Ora hai creato un sito Web di LocalLibrary fantastico, vorrai installarlo su un server Web pubblico in modo che sia accessibile al personale della biblioteca e ai membri su Internet. Questo articolo fornisce una panoramica di come si può trovare un host per la distribuzione del sito Web e di cosa è necessario fare per rendere il sito pronto per la produzione.</dd> +</dl> + +<h2 id="Consulta_anche">Consulta anche</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Installing_on_PWS_Cloud_Foundry">Installare LocalLibrary su PWS/Cloud Foundry</a></dt> + <dd>Questo articolo fornisce una dimostrazione pratica di come installare LocalLibrary sul <a href="http://run.pivotal.io/">Pivotal Web Services PaaS cloud</a>: si tratta di un'alternativa open source completa di Heroku, il servizio cloud PaaS utilizzato nella parte 7 del tutorial, sopra elencato. PWS/Cloud Foundry Merita sicuramente un'occhiata se stai cercando una alternativa ad Heroku o vuoi provare qualcos'altro.</dd> +</dl> + +<h2 id="Aggiungere_altri_tutorials">Aggiungere altri tutorials</h2> + +<div> +<p>Questa è la fine degli articoli del tutorial (per ora). Se desideri estenderlo, altri argomenti interessanti da trattare sono:</p> + +<ul> + <li>Utilizzo delle sessioni.</li> + <li>Autenticazioni.</li> + <li>Autorizzazioni e permessi degli utenti.</li> + <li>Testing di una applicazione Express.</li> + <li>Sicurezza delle applicazioni Express.</li> +</ul> + +<p>And of course, it would be excellent to have an assessment task!</p> +</div> diff --git a/files/it/learn/server-side/index.html b/files/it/learn/server-side/index.html new file mode 100644 index 0000000000..35d72b3443 --- /dev/null +++ b/files/it/learn/server-side/index.html @@ -0,0 +1,52 @@ +--- +title: Server-side website programming +slug: Learn/Server-side +tags: + - Beginner + - CodingScripting + - Intro + - Landing + - Learn + - NeedsTranslation + - Server + - Server-side programming + - Topic + - TopicStub +translation_of: Learn/Server-side +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">The <strong><em>Dynamic Websites </em></strong>–<em><strong> Server-side programming</strong></em> topic is a series of modules that show how to create dynamic websites; websites that deliver customised information in response to HTTP requests. The modules provide a generic introduction to server-side programming, along with specific beginner-level guides on how to use the Django (Python) and Express (Node.js/JavaScript) web frameworks to create basic applications.</p> + +<p>Most major websites use some kind of server-side technology to dynamically display different data as required. For example, imagine how many products are available on Amazon, and imagine how many posts have been written on Facebook? Displaying all of these using completely different static pages would be completely inefficient, so instead such sites display static templates (built using <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, and <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>), and then dynamically update the data displayed inside those templates when needed, e.g. when you want to view a different product on Amazon.</p> + +<p>In the modern world of web development, learning about server-side development is highly recommended.</p> + +<h2 id="Learning_pathway">Learning pathway</h2> + +<p>Getting started with server-side programming is usually easier than with client-side development, because dynamic websites tend to perform a lot of very similar operations (retrieving data from a database and displaying it in a page, validating user-entered data and saving it in a database, checking user permissions and logging users in, etc.), and are constructed using web frameworks that make these and other common web server operations easy.</p> + +<p>A basic knowledge of programming concepts (or of a particular programming language) is useful, but not essential. Similarly, expertise in client-side coding is not required, but a basic knowledge will help you work better with the developers creating your client-side web "front end".</p> + +<p>You will need to understand "how the web works". We recommend that you first read the following topics:</p> + +<ul> + <li><a href="/en-US/docs/Learn/Common_questions/What_is_a_web_server">What is a web server</a></li> + <li><a href="/en-US/docs/Learn/Common_questions/What_software_do_I_need">What software do I need to build a website?</a></li> + <li><a href="/en-US/docs/Learn/Common_questions/Upload_files_to_a_web_server">How do you upload files to a web server?</a></li> +</ul> + +<p>With that basic understanding you'll be ready to work your way through the modules in this section. </p> + +<h2 id="Modules">Modules</h2> + +<p>This topic contains the following modules. You should start with the first module, then go on to one of the following modules, which show how to work with two very popular server-side languages using appropriate web frameworks . </p> + +<dl> + <dt><a href="/en-US/docs/Learn/Server-side/First_steps">Server-side website programming first steps</a></dt> + <dd>This module provides server-technology-agnostic information about server-side website programming, including answers to fundamental questions about server-side programming — "what it is", "how it differs from client-side programming", and "why it is so useful" — and an overview of some of the more popular server-side web frameworks and guidance on how to select the most suitable for your site. Lastly we provide an introductory section on web server security.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Django">Django Web Framework (Python)</a></dt> + <dd>Django is an extremely popular and fully featured server-side web framework, written in Python. The module explains why Django is such a good web server framework, how to set up a development environment and how to perform common tasks with it.</dd> + <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs">Express Web Framework (Node.js/JavaScript)</a></dt> + <dd>Express is a popular web framework, written in JavaScript and hosted within the node.js runtime environment. The module explains some of the key benefits of this framework, how to set up your development environment and how to perform common web development and deployment tasks.</dd> +</dl> |