Share via


Passaggio 2: Creare un'app Flask con visualizzazioni e modelli di pagina

Passaggio precedente: Creare un progetto e una soluzione di Visual Studio

Nel passaggio 1 di questa esercitazione è stata creata un'app Flask con una sola pagina e tutto il codice in un singolo file. Per consentire lo sviluppo futuro, è consigliabile effettuare il refactoring del codice e creare una struttura per i modelli di pagina. In particolare, è opportuno separare il codice per le visualizzazioni dell'app da altri aspetti, ad esempio il codice di avvio.

In questo passaggio viene descritto come:

  • Effettuare il refactoring del codice dell'app per separare le visualizzazioni dal codice di avvio (passaggio 2-1)
  • Eseguire il rendering di una visualizzazione usando un modello di pagina (passaggio 2-2)

Passaggio 2-1: Effettuare il refactoring del progetto per supportare un ulteriore sviluppo

Nel codice creato usando il modello "Progetto Web Flask vuoto" si ha un unico file app.py che contiene il codice di avvio insieme a una singola visualizzazione. Per consentire un ulteriore sviluppo di un'app con più visualizzazioni e modelli, è consigliabile separare questi problemi.

  1. Nella cartella del progetto creare una cartella dell'app denominata HelloFlask facendo clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e selezionando Aggiungi>Nuova cartella.

  2. Nella cartella HelloFlask creare un file denominato __init__.py con il contenuto seguente che crea l'istanza Flask e carica le visualizzazioni dell'app (create nel passaggio successivo):

    from flask import Flask
    app = Flask(__name__)
    
    import HelloFlask.views
    
  3. Nella cartella HelloFlask creare un file denominato views.py con il contenuto seguente. Il nome views.py è importante perché è stato usato import HelloFlask.views all'interno di __init__.py. Se i nomi non corrispondono, verrà visualizzato un errore in fase di esecuzione.

    from flask import Flask
    from HelloFlask import app
    
    @app.route('/')
    @app.route('/home')
    def home():
        return "Hello Flask!"
    

    Oltre a rinominare la funzione e indirizzare a home, questo codice contiene il codice di rendering della pagina da app.py e importa l'oggetto app dichiarato in __init__.py.

  4. In HelloFlask creare la sottocartella templates, che per il momento rimane vuota.

  5. Nella cartella radice del progetto rinominare app.py in runserver.py e fare in modo che il contenuto corrisponda al codice seguente:

    import os
    from HelloFlask import app    # Imports the code from HelloFlask/__init__.py
    
    if __name__ == '__main__':
        HOST = os.environ.get('SERVER_HOST', 'localhost')
    
        try:
            PORT = int(os.environ.get('SERVER_PORT', '5555'))
        except ValueError:
            PORT = 5555
    
        app.run(HOST, PORT)
    
  6. La struttura del progetto avrà un aspetto simile all'immagine seguente:

    Project structure after refactoring the code

  7. Selezionare Debug>Avvia debug (F5) o usare il pulsante Server Web sulla barra degli strumenti (il browser visualizzato potrebbe variare) per avviare l'app e aprire un browser. Provare entrambe le route dell'URL / e /home.

  8. È inoltre possibile impostare punti di interruzione in varie parti del codice e riavviare l'app per seguire la sequenza di avvio. Ad esempio, impostare un punto di interruzione sulle prime righe di runserver.py e *HelloFlask_*init_.py e sulla return "Hello Flask!" riga in views.py. Riavviare quindi l'app (Riavvio del debug>, CTRL+MAIUSC+F5 o il pulsante della barra degli strumenti illustrato di seguito) e scorrere il codice (F10) oppure eseguire da ogni punto di interruzione usando F5.

    Restart button on the debugging toolbar in Visual Studio

  9. Al termine, arrestare l'app.

Eseguire il commit nel controllo del codice sorgente

Dopo aver apportato le modifiche al codice e al test correttamente, è possibile esaminare ed eseguire il commit delle modifiche nel controllo del codice sorgente. Nei passaggi successivi, quando questa esercitazione ricorda di eseguire di nuovo il commit nel controllo del codice sorgente, è possibile fare riferimento a questa sezione.

  1. Selezionare il pulsante delle modifiche nella parte inferiore di Visual Studio (cerchiata di seguito) per passare a Team Explorer.

    Source control changes button on the Visual Studio status bar

  2. In Team Explorer immettere un messaggio per il commit, ad esempio "Refactoring del codice" e selezionare Esegui commit di tutto. Al termine del commit, viene visualizzato un messaggio Commit <hash> creato in locale. Eseguire la sincronizzazione per condividere le modifiche con il server. Per eseguire il push delle modifiche nel repository remoto, selezionare Sincronizza, quindi selezionare Push in Commit in uscita. È anche possibile accumulare più commit locali prima di eseguire il push in remoto.

    Push commits to remote in Team Explorer

Domanda: Con quale frequenza è consigliabile eseguire il commit nel controllo del codice sorgente?

Risposta: Il commit delle modifiche nel controllo del codice sorgente crea un record nel registro modifiche e un punto in corrispondenza del quale è possibile ripristinare il repository, se necessario. Ogni commit può anche essere esaminato per verificare modifiche specifiche. Poiché i commit in Git sono poco costosi, è preferibile eseguire spesso più commit piuttosto che accumulare un numero elevato di modifiche in un singolo commit. Non è necessario eseguire il commit di ogni piccola modifica ai singoli file. In genere, si esegue un commit quando si aggiunge una funzionalità, si modifica una struttura come è stata eseguita in questo passaggio o si esegue il refactoring di un codice. Verificare inoltre con gli altri utenti del proprio team qual è il livello di granularità del commit più adatto per tutti.

La frequenza con cui si esegue il commit e la frequenza con cui si esegue il push del commit a un repository remoto sono due concetti diversi. È possibile accumulare più commit nel repository locale prima di eseguirne il push nel repository remoto. La frequenza dei commit dipende dal modo in cui il team vuole gestire il repository.

Passaggio 2-2: Usare un modello per il rendering di una pagina

La funzione home presente finora in views.py genera solo una risposta HTTP in testo normale per la pagina. Tuttavia, la maggior parte delle pagine Web di scenari reali risponde con pagine HTML formattate che spesso includono dati in tempo reale. Il motivo principale per definire una visualizzazione usando una funzione consiste nel generare contenuto in modo dinamico.

Poiché il valore restituito per la visualizzazione è una stringa, è possibile compilare qualsiasi codice HTML all'interno di una stringa usando contenuto dinamico. Tuttavia, poiché è preferibile separare il markup dai dati, è preferibile inserire il markup in un modello e mantenere i dati nel codice.

  1. I principianti possono modificare views.py in modo che contenga il codice seguente che usa HTML inline per la pagina con contenuto dinamico:

    from datetime import datetime
    from flask import render_template
    from HelloFlask import app
    
    @app.route('/')
    @app.route('/home')
    def home():
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        html_content = "<html><head><title>Hello Flask</title></head><body>"
        html_content += "<strong>Hello Flask!</strong> on " + formatted_now
        html_content += "</body></html>"
    
        return html_content
    
  2. Eseguire l'app e aggiornare la pagina alcune volte per verificare che la data e l'ora siano aggiornate. Al termine, arrestare l'app.

  3. Per convertire il rendering della pagina in modo che usi un modello, creare un file denominato index.html nella cartella templates con il contenuto seguente, dove {{ content }} è un segnaposto o un token di sostituzione (detto anche variabile del modello) per il quale si specifica un valore nel codice:

    <html>
      <head>
        <title>Hello Flask</title>
      </head>
    
      <body>
        {{ content }}
      </body>
    </html>
    
  4. Modificare la funzione home in modo da usare render_template per caricare il modello e specificare un valore per "content", operazione che viene eseguita usando un argomento denominato corrispondente al nome del segnaposto. Flask cerca automaticamente i modelli nella cartella templates, quindi il percorso del modello è relativo a questa cartella:

    def home():
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        return render_template(
            "index.html",
            content = "<strong>Hello, Flask!</strong> on " + formatted_now)
    
  5. Eseguire l'app e visualizzare i risultati. Si noti che il codice HTML inline nel content valore non viene eseguito come HTML perché il motore di creazione modelli (Jinja) esegue automaticamente l'escape del contenuto HTML. L'escape automatico impedisce vulnerabilità accidentali agli attacchi injection. Gli sviluppatori spesso raccolgono l'input da una pagina e lo usano come valore in un altro tramite un segnaposto modello. L'escape funge anche da promemoria che è consigliabile evitare html dal codice.

    Di conseguenza, verificare che templates\index.html contenga segnaposti distinti per ogni blocco di dati all'interno del markup:

    <html>
      <head>
        <title>{{ title }}</title>
      </head>
      <body>
        <strong>{{ message }}</strong>{{ content }}
      </body>
    </html>
    

    Aggiornare quindi la funzione home per specificare i valori per tutti i segnaposto:

    def home():
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        return render_template(
            "index.html",
            title = "Hello Flask",
            message = "Hello, Flask!",
            content = " on " + formatted_now)
    
  6. Eseguire di nuovo l'app e visualizzare l'output sottoposto a rendering corretto.

    Running app using the template

  7. È possibile eseguire il commit delle modifiche nel controllo del codice sorgente e aggiornare il repository remoto. Per altre informazioni, vedere il passaggio 2-1.

Domanda: I modelli di pagina devono trovarsi in un file separato?

Risposta: Anche se i modelli vengono in genere mantenuti in file HTML separati, è possibile usare anche un modello inline. È consigliabile mantenere una separazione pulita tra markup e codice.

Domanda: I modelli devono usare l'estensione html?

Risposta: L'estensione HTML per i file modello di pagina è completamente facoltativa, perché è sempre possibile identificare il percorso relativo esatto del file nel primo argomento della render_template funzione. Tuttavia, Visual Studio (e altri editor) in genere offrono funzionalità come il completamento del codice e la colorazione della sintassi con i file HTML , che superano il fatto che i modelli di pagina non sono HTML.

Quando si usa un progetto Flask, Visual Studio rileva automaticamente quando il file HTML che si sta modificando è effettivamente un modello Flask e fornisce alcune funzionalità complete automaticamente. Ad esempio, quando si inizia a digitare un commento in un modello di pagina Flask, {#, Visual Studio suggerisce automaticamente i caratteri di chiusura #}. Anche i comandi Commenta selezione e Rimuovi commento selezione (nel menu Modifica>Avanzate e sulla barra degli strumenti) usano i commenti dei modelli anziché i commenti HTML.

Domanda: I modelli possono essere organizzati in ulteriori sottocartelle?

Risposta: Sì, è possibile usare sottocartelle e quindi fare riferimento al percorso relativo in templates nelle chiamate a render_template. In questo modo si possono creare in modo efficace gli spazi dei nomi per i modelli.

Passaggi successivi

Approfondimento