Come interrogare tabelle e paginare dati in Flask-SQLAlchemy

L’autore ha selezionato il Fondo per il Software Libero e Open Source per ricevere una donazione nell’ambito del programma Scrivi per le Donazioni.

Introduzione

Flask è un framework web leggero in Python che fornisce strumenti utili e funzionalità per creare applicazioni web nel linguaggio Python. SQLAlchemy è un toolkit SQL che offre accesso efficiente e ad alte prestazioni ai database relazionali. Fornisce modi per interagire con diversi motori di database come SQLite, MySQL e PostgreSQL. Ti dà accesso alle funzionalità SQL del database. E ti fornisce anche un Object Relational Mapper (ORM), che ti permette di fare query e gestire i dati usando semplici oggetti e metodi Python. Flask-SQLAlchemy è un’estensione di Flask che facilita l’uso di SQLAlchemy con Flask, fornendoti strumenti e metodi per interagire con il tuo database nelle tue applicazioni Flask tramite SQLAlchemy.

In questo tutorial, utilizzerai Flask e Flask-SQLAlchemy per creare un sistema di gestione dipendenti con un database che ha una tabella per i dipendenti. Ogni dipendente avrà un ID univoco, un nome, un cognome, un’email univoca, un valore intero per l’età, una data per il giorno in cui si è unito all’azienda e un valore booleano per determinare se un dipendente è attualmente attivo o fuori sede.

Utilizzerai la shell di Flask per interrogare una tabella e ottenere record della tabella basati su un valore di colonna (ad esempio, un’email). Recupererai i record dei dipendenti in determinate condizioni, come ottenere solo dipendenti attivi o ottenere un elenco di dipendenti fuori sede. Ordinerai i risultati per un valore di colonna e conterai e limiterai i risultati della query. Infine, utilizzerai la paginazione per visualizzare un certo numero di dipendenti per pagina in un’applicazione web.

Prerequisiti

Passaggio 1 — Configurazione del Database e del Modello

In questo passaggio, installerai i pacchetti necessari e configurerai la tua applicazione Flask, il database Flask-SQLAlchemy e il modello dell’impiegato che rappresenta la tabella employee dove verranno memorizzati i dati dei dipendenti. Inserterai alcuni dipendenti nella tabella employee, e aggiungerai un percorso e una pagina dove tutti i dipendenti vengono visualizzati sulla pagina iniziale della tua applicazione.

Per prima cosa, con il tuo ambiente virtuale attivato, installa Flask e Flask-SQLAlchemy:

  1. pip install Flask Flask-SQLAlchemy

Una volta completata l’installazione, riceverai un output con la seguente riga alla fine:

Output
Successfully installed Flask-2.1.2 Flask-SQLAlchemy-2.5.1 Jinja2-3.1.2 MarkupSafe-2.1.1 SQLAlchemy-1.4.37 Werkzeug-2.1.2 click-8.1.3 greenlet-1.1.2 itsdangerous-2.1.2

Con i pacchetti richiesti installati, apri un nuovo file chiamato app.py nella tua directory flask_app. Questo file conterrà il codice per configurare il database e le tue route Flask:

  1. nano app.py

Aggiungi il seguente codice a app.py. Questo codice imposterà un database SQLite e un modello di database per dipendenti rappresentando la tabella employee che userai per memorizzare i dati dei dipendenti:

flask_app/app.py
import os
from flask import Flask, render_template, request, url_for, redirect
from flask_sqlalchemy import SQLAlchemy


basedir = os.path.abspath(os.path.dirname(__file__))

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] =\
        'sqlite:///' + os.path.join(basedir, 'database.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)


class Employee(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(100), nullable=False)
    lastname = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    age = db.Column(db.Integer, nullable=False)
    hire_date = db.Column(db.Date, nullable=False)
    active = db.Column(db.Boolean, nullable=False)

    def __repr__(self):
        return f'<Employee {self.firstname} {self.lastname}>'

Salva e chiudi il file.

Qui, importi il modulo os, che ti fornisce accesso a interfacce del sistema operativo varie. Lo userai per costruire un percorso del file per il tuo database database.db.

Dal pacchetto flask, importi gli helper di cui hai bisogno per la tua applicazione: la classe Flask per creare un’istanza dell’applicazione Flask, render_template() per renderizzare i modelli, l’oggetto request per gestire le richieste, url_for() per costruire URL e la funzione redirect() per reindirizzare gli utenti. Per ulteriori informazioni sulle route e sui modelli, consulta Come utilizzare i modelli in un’applicazione Flask.

Successivamente, importi la classe SQLAlchemy dall’estensione Flask-SQLAlchemy, che ti fornisce accesso a tutte le funzioni e classi di SQLAlchemy, oltre a helper e funzionalità che integrano Flask con SQLAlchemy. Lo utilizzerai per creare un oggetto database che si connette alla tua applicazione Flask.

Per costruire un percorso per il file del database, si definisce una directory di base come directory corrente. Si utilizza la funzione os.path.abspath() per ottenere il percorso assoluto della directory del file corrente. La variabile speciale __file__ contiene il percorso del file app.py corrente. Si memorizza il percorso assoluto della directory di base in una variabile chiamata basedir.

Si crea quindi un’istanza dell’applicazione Flask chiamata app, che si utilizza per configurare due chiavi di configurazione di Flask-SQLAlchemy chiavi di configurazione:

  • SQLALCHEMY_DATABASE_URI: L’URI del database per specificare il database con cui si desidera stabilire una connessione. In questo caso, l’URI segue il formato sqlite:///percorso/al/database.db. Si utilizza la funzione os.path.join() per unire intelligentemente la directory di base che è stata costruita e memorizzata nella variabile basedir con il nome del file database.db. Ciò si collegherà a un file del database database.db nella directory del tuo flask_app. Il file verrà creato una volta che si inizializza il database.

  • SQLALCHEMY_TRACK_MODIFICATIONS: Una configurazione per abilitare o disabilitare il tracciamento delle modifiche degli oggetti. Lo imposti su Falso per disabilitare il tracciamento, il che utilizza meno memoria. Per ulteriori informazioni, consulta la pagina di configurazione nella documentazione di Flask-SQLAlchemy.

Dopo aver configurato SQLAlchemy impostando un URI del database e disabilitando il tracciamento, crei un oggetto database utilizzando la classe SQLAlchemy, passando l’istanza dell’applicazione per connettere la tua applicazione Flask con SQLAlchemy. Archivi l’oggetto del tuo database in una variabile chiamata db, che utilizzerai per interagire con il database.

Dopo aver configurato l’istanza dell’applicazione e l’oggetto del database, erediti dalla classe db.Model per creare un modello di database chiamato Employee. Questo modello rappresenta la tabella employee e ha le seguenti colonne:

  • id: L’ID dell’impiegato, una chiave primaria intera.
  • firstname: Il nome dell’impiegato, una stringa con una lunghezza massima di 100 caratteri. nullable=False significa che questa colonna non deve essere vuota.
  • lastname: Il cognome dell’impiegato, una stringa con una lunghezza massima di 100 caratteri. nullable=False significa che questa colonna non deve essere vuota.
  • email: L’email dell’impiegato, una stringa con una lunghezza massima di 100 caratteri. unique=True significa che ogni email deve essere unica. nullable=False significa che il suo valore non deve essere vuoto.
  • age: L’età dell’impiegato, un valore intero.
  • hire_date: La data in cui l’impiegato è stato assunto. Imposti db.Date come tipo di colonna per dichiararla come una colonna che contiene date.
  • active: Una colonna che conterrà un valore booleano per indicare se l’impiegato è attualmente attivo o fuori dall’ufficio.

La funzione speciale __repr__ ti permette di dare a ciascun oggetto una rappresentazione stringa per riconoscerlo per scopi di debug. In questo caso, usi il nome e il cognome dell’impiegato per rappresentare ciascun oggetto impiegato.

Ora che hai impostato la connessione al database e il modello dell’impiegato, scriverai un programma Python per creare il tuo database e la tabella employee e popolare la tabella con alcuni dati dei dipendenti.

Apri un nuovo file chiamato init_db.py nella tua directory flask_app:

  1. nano init_db.py

Aggiungi il seguente codice per eliminare le tabelle del database esistenti per iniziare da un database pulito, creare la tabella employee e inserire nove dipendenti al suo interno:

flask_app/init_db.py
from datetime import date
from app import db, Employee

db.drop_all()
db.create_all()

e1 = Employee(firstname='John',
              lastname='Doe',
              email='[email protected]',
              age=32,
              hire_date=date(2012, 3, 3),
              active=True
              )

e2 = Employee(firstname='Mary',
              lastname='Doe',
              email='[email protected]',
              age=38,
              hire_date=date(2016, 6, 7),
              active=True
              )

e3 = Employee(firstname='Jane',
              lastname='Tanaka',
              email='[email protected]',
              age=32,
              hire_date=date(2015, 9, 12),
              active=False
              )

e4 = Employee(firstname='Alex',
              lastname='Brown',
              email='[email protected]',
              age=29,
              hire_date=date(2019, 1, 3),
              active=True
              )

e5 = Employee(firstname='James',
              lastname='White',
              email='[email protected]',
              age=24,
              hire_date=date(2021, 2, 4),
              active=True
              )

e6 = Employee(firstname='Harold',
              lastname='Ishida',
              email='[email protected]',
              age=52,
              hire_date=date(2002, 3, 6),
              active=False
              )

e7 = Employee(firstname='Scarlett',
              lastname='Winter',
              email='[email protected]',
              age=22,
              hire_date=date(2021, 4, 7),
              active=True
              )

e8 = Employee(firstname='Emily',
              lastname='Vill',
              email='[email protected]',
              age=27,
              hire_date=date(2019, 6, 9),
              active=True
              )

e9 = Employee(firstname='Mary',
              lastname='Park',
              email='[email protected]',
              age=30,
              hire_date=date(2021, 8, 11),
              active=True
              )

db.session.add_all([e1, e2, e3, e4, e5, e6, e7, e8, e9])

db.session.commit()

Qui, importi la classe date() dal modulo datetime per usarla per impostare le date di assunzione dei dipendenti.

Importi l’oggetto del database e il modello Employee. Chiami la funzione db.drop_all() per eliminare tutte le tabelle esistenti per evitare il rischio di avere una tabella employee già popolata nel database, che potrebbe causare problemi. Ciò cancella tutti i dati del database ogni volta che esegui il programma init_db.py. Per ulteriori informazioni su come creare, modificare ed eliminare le tabelle del database, consulta Come utilizzare Flask-SQLAlchemy per interagire con i database in un’applicazione Flask.

Quindi crei diverse istanze del modello Employee, che rappresentano i dipendenti che verranno interrogati in questo tutorial, e li aggiungi alla sessione del database utilizzando la funzione db.session.add_all(). Infine, confermi la transazione e applichi le modifiche al database utilizzando il db.session.commit().

Salva e chiudi il file.

Esegui il programma init_db.py:

  1. python init_db.py

Per dare un’occhiata ai dati che hai aggiunto al tuo database, assicurati che il tuo ambiente virtuale sia attivato, e apri la shell di Flask per interrogare tutti i dipendenti e visualizzare i loro dati:

  1. flask shell

Esegui il seguente codice per interrogare tutti i dipendenti e visualizzare i loro dati:

  1. from app import db, Employee
  2. employees = Employee.query.all()
  3. for employee in employees:
  4. print(employee.firstname, employee.lastname)
  5. print('Email:', employee.email)
  6. print('Age:', employee.age)
  7. print('Hired:', employee.hire_date)
  8. if employee.active:
  9. print('Active')
  10. else:
  11. print('Out of Office')
  12. print('----')

Utilizzi il metodo all() dell’attributo query per ottenere tutti i dipendenti. Fai un loop attraverso i risultati e visualizzi le informazioni del dipendente. Per la colonna active, utilizzi un’istruzione condizionale per visualizzare lo stato attuale del dipendente, o 'Attivo' o 'Fuori Ufficio'.

Riceverai il seguente output:

Output
John Doe Email: [email protected] Age: 32 Hired: 2012-03-03 Active ---- Mary Doe Email: [email protected] Age: 38 Hired: 2016-06-07 Active ---- Jane Tanaka Email: [email protected] Age: 32 Hired: 2015-09-12 Out of Office ---- Alex Brown Email: [email protected] Age: 29 Hired: 2019-01-03 Active ---- James White Email: [email protected] Age: 24 Hired: 2021-02-04 Active ---- Harold Ishida Email: [email protected] Age: 52 Hired: 2002-03-06 Out of Office ---- Scarlett Winter Email: [email protected] Age: 22 Hired: 2021-04-07 Active ---- Emily Vill Email: [email protected] Age: 27 Hired: 2019-06-09 Active ---- Mary Park Email: [email protected] Age: 30 Hired: 2021-08-11 Active ----

Puoi vedere che tutti i dipendenti che abbiamo aggiunto al database vengono visualizzati correttamente.

Esci dalla shell di Flask:

  1. exit()

Successivamente, creerai un percorso Flask per visualizzare i dipendenti. Apri app.py per modificarlo:

  1. nano app.py

Aggiungi il seguente percorso alla fine del file:

flask_app/app.py
...

@app.route('/')
def index():
    employees = Employee.query.all()
    return render_template('index.html', employees=employees)

Salva e chiudi il file.

Questo interroga tutti i dipendenti, rende un modello index.html, e passa loro i dipendenti che hai recuperato.

Crea una directory dei modelli e un modello base:

  1. mkdir templates
  2. nano templates/base.html

Aggiungi quanto segue a base.html:

flask_app/templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        .title {
            margin: 5px;
        }

        .content {
            margin: 5px;
            width: 100%;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
        }

        .employee {
            flex: 20%;
            padding: 10px;
            margin: 5px;
            background-color: #f3f3f3;
            inline-size: 100%;
        }

        .name {
            color: #00a36f;
            text-decoration: none;
        }

        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }

        .pagination {
            margin: 0 auto;
        }

        .pagination span {
            font-size: 2em;
            margin-right: 10px;
        }

        .page-number {
            color: #d64161;
            padding: 5px;
            text-decoration: none;
        }

        .current-page-number {
            color: #666
        }

    </style>
</head>
<body>
    <nav>
        <a href="{{ url_for('index') }}">FlaskApp</a>
        <a href="#">About</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

Salva e chiudi il file.

Qui, si utilizza un blocco di titolo e si aggiunge qualche stile CSS. Si aggiunge una barra di navigazione con due voci, una per la pagina indice e una per una pagina About inattiva. Questa barra di navigazione sarà riutilizzata in tutta l’applicazione nei modelli che ereditano da questo modello di base. Il blocco di contenuto verrà sostituito con il contenuto di ciascuna pagina. Per ulteriori informazioni sui modelli, controlla Come utilizzare i modelli in un’applicazione Flask.

Successivamente, apri un nuovo modello index.html che hai reso in app.py:

  1. nano templates/index.html

Aggiungi il seguente codice al file:

flask_app/templates/index.html
{% extends 'base.html' %}

{% block content %}
    <h1 class="title">{% block title %} Employees {% endblock %}</h1>
    <div class="content">
        {% for employee in employees %}
            <div class="employee">
                <p><b>#{{ employee.id }}</b></p>
                <b>
                    <p class="name">{{ employee.firstname }} {{ employee.lastname }}</p>
                </b>
                <p>{{ employee.email }}</p>
                <p>{{ employee.age }} years old.</p>
                <p>Hired: {{ employee.hire_date }}</p>
                {% if employee.active %}
                    <p><i>(Active)</i></p>
                {% else %}
                    <p><i>(Out of Office)</i></p>
                {% endif %}
            </div>
        {% endfor %}
    </div>
{% endblock %}

Qui, si itera attraverso gli impiegati e si visualizzano le informazioni di ciascun impiegato. Se l’impiegato è attivo si aggiunge una etichetta (Attivo), altrimenti si visualizza una etichetta (Fuori dall’ufficio).

Salva e chiudi il file.

Mentre sei nella directory flask_app con il tuo ambiente virtuale attivato, comunica a Flask dell’applicazione (app.py in questo caso) utilizzando la variabile d’ambiente FLASK_APP. Successivamente imposta la variabile d’ambiente FLASK_ENV su development per eseguire l’applicazione in modalità di sviluppo e ottenere accesso al debugger. Per ulteriori informazioni sul debugger di Flask, vedi Come Gestire gli Errori in un’Applicazione Flask. Utilizza i seguenti comandi per farlo:

  1. export FLASK_APP=app
  2. export FLASK_ENV=development

Successivamente, esegui l’applicazione:

  1. flask run

Con il server di sviluppo in esecuzione, visita l’URL seguente utilizzando il tuo browser:

http://127.0.0.1:5000/

Vedrai gli impiegati che hai aggiunto al database in una pagina simile a questa:

Lascia il server in esecuzione, apri un’altra finestra di terminale e procedi con il passaggio successivo.

Hai visualizzato gli impiegati che hai nel tuo database sulla pagina di indice. Successivamente, utilizzerai la shell di Flask per interrogare gli impiegati utilizzando metodi diversi.

Passaggio 2 — Interrogare i Record

In questo passaggio, utilizzerai la shell di Flask per interrogare i record, filtrare e recuperare risultati utilizzando metodi e condizioni multipli.

Con il tuo ambiente di programmazione attivato, imposta le variabili FLASK_APP e FLASK_ENV, e apri la shell di Flask:

  1. export FLASK_APP=app
  2. export FLASK_ENV=development
  3. flask shell

Importa l’oggetto db e il modello Employee:

  1. from app import db, Employee

Recupero di tutti i record

Come hai visto nel passaggio precedente, puoi utilizzare il metodo all() sull’attributo query per ottenere tutti i record in una tabella:

  1. all_employees = Employee.query.all()
  2. print(all_employees)

L’output sarà una lista di oggetti che rappresentano tutti i dipendenti:

Output
[<Employee John Doe>, <Employee Mary Doe>, <Employee Jane Tanaka>, <Employee Alex Brown>, <Employee James White>, <Employee Harold Ishida>, <Employee Scarlett Winter>, <Employee Emily Vill>, <Employee Mary Park>]

Recupero del primo record

Allo stesso modo, puoi utilizzare il metodo first() per ottenere il primo record:

  1. first_employee = Employee.query.first()
  2. print(first_employee)

L’output sarà un oggetto che contiene i dati del primo dipendente:

Output
<Employee John Doe>

Recupero di un record per ID

Nella maggior parte delle tabelle del database, i record sono identificati con un ID univoco. Flask-SQLAlchemy ti consente di recuperare un record utilizzando il suo ID con il metodo get():

  1. employee5 = Employee.query.get(5)
  2. employee3 = Employee.query.get(3)
  3. print(f'{employee5} | ID: {employee5.id}')
  4. print(f'{employee3} | ID: {employee3.id}')
Output
<Employee James White> | ID: 5 <Employee Jane Tanaka> | ID: 3

Recupero di un record o di più record per valore di colonna

Per ottenere un record utilizzando il valore di una delle sue colonne, utilizzare il metodo filter_by(). Ad esempio, per ottenere un record utilizzando il suo valore ID, simile al metodo get():

  1. employee = Employee.query.filter_by(id=1).first()
  2. print(employee)
Output
<Employee John Doe>

Si utilizza first() perché filter_by() può restituire più risultati.

Nota: Per ottenere un record per ID, utilizzare il metodo get() è un approccio migliore.

Per un altro esempio, è possibile ottenere un dipendente utilizzando la sua età:

  1. employee = Employee.query.filter_by(age=52).first()
  2. print(employee)
Output
<Employee Harold Ishida>

Per un esempio in cui il risultato della query contiene più di un record corrispondente, utilizzare la colonna firstname e il nome Mary, che è un nome condiviso da due dipendenti:

  1. mary = Employee.query.filter_by(firstname='Mary').all()
  2. print(mary)
Output
[<Employee Mary Doe>, <Employee Mary Park>]

Qui, si utilizza all() per ottenere l’intero elenco. È anche possibile utilizzare first() per ottenere solo il primo risultato:

  1. mary = Employee.query.filter_by(firstname='Mary').first()
  2. print(mary)
Output
<Employee Mary Doe>

Hai recuperato record attraverso valori di colonna. Successivamente, eseguirai una query sulla tabella utilizzando condizioni logiche.

Passaggio 3 — Filtraggio dei record utilizzando condizioni logiche

Nelle complesse applicazioni web complete, spesso è necessario interrogare i record dal database utilizzando condizioni complesse, come ad esempio recuperare dipendenti in base a una combinazione di condizioni che tengono conto della loro posizione, disponibilità, ruolo e responsabilità. In questo passaggio, eserciterai l’uso degli operatori condizionali. Utilizzerai il metodo filter() sull’attributo query per filtrare i risultati della query utilizzando condizioni logiche con diversi operatori. Ad esempio, è possibile utilizzare operatori logici per recuperare un elenco dei dipendenti attualmente fuori dall’ufficio, o dipendenti in attesa di una promozione, e magari fornire un calendario del periodo di ferie dei dipendenti, ecc.

Uguaglianza

L’operatore logico più semplice che puoi utilizzare è l’operatore di uguaglianza ==, che si comporta in modo simile a filter_by(). Ad esempio, per ottenere tutti i record in cui il valore della colonna firstname è Mary, è possibile utilizzare il metodo filter() in questo modo:

  1. mary = Employee.query.filter(Employee.firstname == 'Mary').all()
  2. print(mary)

Qui si utilizza la sintassi Model.column == value come argomento del metodo filter(). Il metodo filter_by() è un’abbreviazione per questa sintassi.

Il risultato è lo stesso del risultato del metodo filter_by() con la stessa condizione:

Output
[<Employee Mary Doe>, <Employee Mary Park>]

Come filter_by(), è possibile utilizzare anche il metodo first() per ottenere il primo risultato:

  1. mary = Employee.query.filter(Employee.firstname == 'Mary').first()
  2. print(mary)
Output
<Employee Mary Doe>

Non Uguale

Il metodo filter() ti consente di utilizzare l’operatore != di Python per ottenere record. Ad esempio, per ottenere una lista di dipendenti fuori sede, puoi utilizzare il seguente approccio:

  1. out_of_office_employees = Employee.query.filter(Employee.active != True).all()
  2. print(out_of_office_employees)
Output
[<Employee Jane Tanaka>, <Employee Harold Ishida>]

Qui si utilizza la condizione Employee.active != True per filtrare i risultati.

Minore Di

Puoi utilizzare l’operatore < per ottenere un record in cui il valore di una determinata colonna è inferiore al valore specificato. Ad esempio, per ottenere una lista di dipendenti di età inferiore ai 32 anni:

  1. employees_under_32 = Employee.query.filter(Employee.age < 32).all()
  2. for employee in employees_under_32:
  3. print(employee.firstname, employee.lastname)
  4. print('Age: ', employee.age)
  5. print('----')
Output
Alex Brown Age: 29 ---- James White Age: 24 ---- Scarlett Winter Age: 22 ---- Emily Vill Age: 27 ---- Mary Park Age: 30 ----

Utilizza l’operatore <= per record che sono inferiori o uguali al valore specificato. Ad esempio, per includere i dipendenti di 32 anni nella query precedente:

  1. employees_32_or_younger = Employee.query.filter(Employee.age <=32).all()
  2. for employee in employees_32_or_younger:
  3. print(employee.firstname, employee.lastname)
  4. print('Age: ', employee.age)
  5. print('----')
Output
John Doe Age: 32 ---- Jane Tanaka Age: 32 ---- Alex Brown Age: 29 ---- James White Age: 24 ---- Scarlett Winter Age: 22 ---- Emily Vill Age: 27 ---- Mary Park Age: 30 ----

Maggiore Di

Analogamente, l’operatore > ottiene un record in cui il valore di una determinata colonna è maggiore del valore specificato. Ad esempio, per ottenere dipendenti oltre i 32 anni:

  1. employees_over_32 = Employee.query.filter(Employee.age > 32).all()
  2. for employee in employees_over_32:
  3. print(employee.firstname, employee.lastname)
  4. print('Age: ', employee.age)
  5. print('----')
Output
Mary Doe Age: 38 ---- Harold Ishida Age: 52 ----

E l’operatore >= è per i record che sono maggiori o uguali al valore specificato. Ad esempio, puoi nuovamente includere i dipendenti di 32 anni nella query precedente:

  1. employees_32_or_older = Employee.query.filter(Employee.age >=32).all()
  2. for employee in employees_32_or_older:
  3. print(employee.firstname, employee.lastname)
  4. print('Age: ', employee.age)
  5. print('----')
Output
John Doe Age: 32 ---- Mary Doe Age: 38 ---- Jane Tanaka Age: 32 ---- Harold Ishida Age: 52 ----

In

SQLAlchemy fornisce anche un modo per ottenere record in cui il valore di una colonna corrisponde a un valore da un dato elenco di valori utilizzando il metodo in_() sulla colonna in questo modo:

  1. names = ['Mary', 'Alex', 'Emily']
  2. employees = Employee.query.filter(Employee.firstname.in_(names)).all()
  3. print(employees)
Output
[<Employee Mary Doe>, <Employee Alex Brown>, <Employee Emily Vill>, <Employee Mary Park>]

Qui, si utilizza una condizione con la sintassi Modello.colonna.in_(iterabile), dove iterabile è qualsiasi tipo di oggetto che puoi iterare. Per un altro esempio, è possibile utilizzare la funzione Python range() per ottenere dipendenti di una certa fascia d’età. La seguente query ottiene tutti i dipendenti che sono nella loro trentina.

  1. employees_in_30s = Employee.query.filter(Employee.age.in_(range(30, 40))).all()
  2. for employee in employees_in_30s:
  3. print(employee.firstname, employee.lastname)
  4. print('Age: ', employee.age)
  5. print('----')
Output
John Doe Age: 32 ---- Mary Doe Age: 38 ---- Jane Tanaka Age: 32 ---- Mary Park Age: 30 ----

Non In

Simile al metodo in_(), è possibile utilizzare il metodo not_in() per ottenere record in cui il valore di una colonna non è presente in un dato iterabile:

  1. names = ['Mary', 'Alex', 'Emily']
  2. employees = Employee.query.filter(Employee.firstname.not_in(names)).all()
  3. print(employees)
Output
[<Employee John Doe>, <Employee Jane Tanaka>, <Employee James White>, <Employee Harold Ishida>, <Employee Scarlett Winter>]

Qui, si ottengono tutti i dipendenti tranne quelli con un nome in lista nomi.

E

È possibile unire diverse condizioni utilizzando la funzione db.and_(), che funziona come l’operatore and di Python.

Per esempio, supponiamo che tu voglia ottenere tutti i dipendenti che hanno 32 anni e sono attualmente attivi. Innanzitutto, puoi controllare chi ha 32 anni usando il metodo filter_by() (puoi anche usare filter() se preferisci):

  1. for employee in Employee.query.filter_by(age=32).all():
  2. print(employee)
  3. print('Age:', employee.age)
  4. print('Active:', employee.active)
  5. print('-----')
Output
<Employee John Doe> Age: 32 Active: True ----- <Employee Jane Tanaka> Age: 32 Active: False -----

Qui vedi che John e Jane sono i dipendenti che hanno 32 anni. John è attivo e Jane è fuori dall’ufficio.

Per ottenere i dipendenti che hanno 32 anni e sono attivi, userai due condizioni con il metodo filter():

  • Employee.age == 32
  • Employee.active == True

Per unire queste due condizioni insieme, usa la funzione db.and_() in questo modo:

  1. active_and_32 = Employee.query.filter(db.and_(Employee.age == 32,
  2. Employee.active == True)).all()
  3. print(active_and_32)
Output
[<Employee John Doe>]

Qui, usi la sintassi filter(db.and_(condizione1, condizione2)).

Utilizzando all() sulla query si ottiene una lista di tutti i record che soddisfano le due condizioni. Puoi usare il metodo first() per ottenere il primo risultato:

  1. active_and_32 = Employee.query.filter(db.and_(Employee.age == 32,
  2. Employee.active == True)).first()
  3. print(active_and_32)
Output
<Employee John Doe>

Per un esempio più complesso, puoi utilizzare db.and_() con la funzione date() per ottenere i dipendenti assunti in un determinato intervallo di tempo. In questo esempio, ottieni tutti i dipendenti assunti nell’anno 2019:

  1. from datetime import date
  2. hired_in_2019 = Employee.query.filter(db.and_(Employee.hire_date >= date(year=2019, month=1, day=1), Employee.hire_date < date(year=2020, month=1, day=1))).all()
  3. for employee in hired_in_2019:
  4. print(employee, ' | Hired: ', employee.hire_date)
Output
<Employee Alex Brown> | Hired: 2019-01-03 <Employee Emily Vill> | Hired: 2019-06-09

Qui importi la funzione date(), e filtrare i risultati utilizzando la funzione db.and_() per combinare le seguenti due condizioni:

  • Employee.hire_date >= date(year=2019, month=1, day=1): Questo è True per i dipendenti assunti il primo gennaio 2019 o successivamente.
  • Employee.hire_date < date(year=2020, month=1, day=1): Questo è Vero per i dipendenti assunti prima del primo gennaio 2020.

Combinando le due condizioni si ottengono dipendenti assunti dal primo giorno del 2019 e prima del primo giorno del 2020.

O

Simile a db.and_(), la funzione db.or_() combina due condizioni e si comporta come l’operatore or in Python. Recupera tutti i record che soddisfano una delle due condizioni. Ad esempio, per ottenere dipendenti di età 32 o 52, è possibile combinare due condizioni con la funzione db.or_() come segue:

  1. employees_32_or_52 = Employee.query.filter(db.or_(Employee.age == 32, Employee.age == 52)).all()
  2. for e in employees_32_or_52:
  3. print(e, '| Age:', e.age)
Output
<Employee John Doe> | Age: 32 <Employee Jane Tanaka> | Age: 32 <Employee Harold Ishida> | Age: 52

Puoi anche utilizzare i metodi startswith() e endswith() sui valori di stringa nelle condizioni che passi al metodo filter(). Ad esempio, per ottenere tutti i dipendenti il cui nome inizia con la stringa 'M' e quelli con un cognome che termina con la stringa 'e':

  1. employees = Employee.query.filter(db.or_(Employee.firstname.startswith('M'), Employee.lastname.endswith('e'))).all()
  2. for e in employees:
  3. print(e)
Output
<Employee John Doe> <Employee Mary Doe> <Employee James White> <Employee Mary Park>

Qui combini le seguenti due condizioni:

  • Employee.firstname.startswith('M'): Corrisponde ai dipendenti con un nome che inizia con 'M'.
  • Employee.lastname.endswith('e'): Corrisponde ai dipendenti con un cognome che termina con 'e'.

Ora puoi filtrare i risultati della query utilizzando condizioni logiche nelle tue applicazioni Flask-SQLAlchemy. Successivamente, ordinerai, limiterai e conterai i risultati ottenuti dal database.

Passo 4 — Ordinare, Limitare e Contare i Risultati

Nelle applicazioni web, spesso è necessario ordinare i record durante la loro visualizzazione. Ad esempio, potresti avere una pagina per mostrare le assunzioni più recenti in ogni dipartimento per informare il resto del team sulle nuove assunzioni, oppure puoi ordinare i dipendenti visualizzando prima le assunzioni più datate per riconoscere i dipendenti con maggiore anzianità. Sarà anche necessario limitare i risultati in alcuni casi, ad esempio mostrando solo le tre assunzioni più recenti in una piccola barra laterale. E spesso è necessario contare i risultati di una query, ad esempio per visualizzare il numero di dipendenti attualmente attivi. In questo passaggio, imparerai come ordinare, limitare e contare i risultati.

Ordinare i Risultati

Per ordinare i risultati utilizzando i valori di una specifica colonna, utilizza il metodo order_by(). Ad esempio, per ordinare i risultati per il nome dei dipendenti:

  1. employees = Employee.query.order_by(Employee.firstname).all()
  2. print(employees)
Output
[<Employee Alex Brown>, <Employee Emily Vill>, <Employee Harold Ishida>, <Employee James White>, <Employee Jane Tanaka>, <Employee John Doe>, <Employee Mary Doe>, <Employee Mary Park>, <Employee Scarlett Winter>]

Come mostrato in output, i risultati sono ordinati in ordine alfabetico per il nome del dipendente.

Puoi ordinare anche per altre colonne. Ad esempio, puoi utilizzare il cognome per ordinare i dipendenti:

  1. employees = Employee.query.order_by(Employee.lastname).all()
  2. print(employees)
Output
[<Employee Alex Brown>, <Employee John Doe>, <Employee Mary Doe>, <Employee Harold Ishida>, <Employee Mary Park>, <Employee Jane Tanaka>, <Employee Emily Vill>, <Employee James White>, <Employee Scarlett Winter>]

Puoi anche ordinare i dipendenti per la loro data di assunzione:

  1. em_ordered_by_hire_date = Employee.query.order_by(Employee.hire_date).all()
  2. for employee in em_ordered_by_hire_date:
  3. print(employee.firstname, employee.lastname, employee.hire_date)
Output
Harold Ishida 2002-03-06 John Doe 2012-03-03 Jane Tanaka 2015-09-12 Mary Doe 2016-06-07 Alex Brown 2019-01-03 Emily Vill 2019-06-09 James White 2021-02-04 Scarlett Winter 2021-04-07 Mary Park 2021-08-11

Come mostrato nell’output, questo ordina i risultati dall’assunzione più precoce alla più recente. Per invertire l’ordine e renderlo discendente dalla più recente assunzione alla più precoce, utilizzare il metodo desc() in questo modo:

  1. em_ordered_by_hire_date_desc = Employee.query.order_by(Employee.hire_date.desc()).all()
  2. for employee in em_ordered_by_hire_date_desc:
  3. print(employee.firstname, employee.lastname, employee.hire_date)
Output
Mary Park 2021-08-11 Scarlett Winter 2021-04-07 James White 2021-02-04 Emily Vill 2019-06-09 Alex Brown 2019-01-03 Mary Doe 2016-06-07 Jane Tanaka 2015-09-12 John Doe 2012-03-03 Harold Ishida 2002-03-06

Puoi anche combinare il metodo order_by() con il metodo filter() per ordinare i risultati filtrati. Nell’esempio seguente vengono presi tutti i dipendenti assunti nel 2021 e ordinati per età:

  1. from datetime import date
  2. hired_in_2021 = Employee.query.filter(db.and_(Employee.hire_date >= date(year=2021, month=1, day=1), Employee.hire_date < date(year=2022, month=1, day=1))).order_by(Employee.age).all()
  3. for employee in hired_in_2021:
  4. print(employee.firstname, employee.lastname,
  5. employee.hire_date, '| Age', employee.age)
Output
Scarlett Winter 2021-04-07 | Age 22 James White 2021-02-04 | Age 24 Mary Park 2021-08-11 | Age 30

Qui, si utilizza la funzione db.and_() con due condizioni: Employee.hire_date >= date(year=2021, month=1, day=1) per i dipendenti assunti il primo giorno del 2021 o successivamente, e Employee.hire_date < date(year=2022, month=1, day=1) per i dipendenti assunti prima del primo giorno del 2022. Successivamente si utilizza il metodo order_by() per ordinare i dipendenti risultanti per età.

Limitare i Risultati

Nella maggior parte dei casi reali, quando si interroga una tabella del database, si possono ottenere fino a milioni di risultati corrispondenti, ed è talvolta necessario limitare i risultati a un certo numero. Per limitare i risultati in Flask-SQLAlchemy, è possibile utilizzare il metodo limit(). Nell’esempio seguente si interroga la tabella employee e vengono restituiti solo i primi tre risultati corrispondenti:

  1. employees = Employee.query.limit(3).all()
  2. print(employees)
Output
[<Employee John Doe>, <Employee Mary Doe>, <Employee Jane Tanaka>]

Puoi utilizzare limit() con altri metodi, come filter e order_by. Ad esempio, puoi ottenere gli ultimi due dipendenti assunti nel 2021 utilizzando il metodo limit() in questo modo:

  1. from datetime import date
  2. hired_in_2021 = Employee.query.filter(db.and_(Employee.hire_date >= date(year=2021, month=1, day=1), Employee.hire_date < date(year=2022, month=1, day=1))).order_by(Employee.age).limit(2).all()
  3. for employee in hired_in_2021:
  4. print(employee.firstname, employee.lastname,
  5. employee.hire_date, '| Age', employee.age)
Output
Scarlett Winter 2021-04-07 | Age 22 James White 2021-02-04 | Age 24

Qui, usi la stessa query della sezione precedente con un ulteriore metodo limit(2).

Contare i risultati

Per contare il numero di risultati di una query, puoi usare il metodo count(). Ad esempio, per ottenere il numero di dipendenti attualmente nel database:

  1. employee_count = Employee.query.count()
  2. print(employee_count)
Output
9

Puoi combinare il metodo count() con altri metodi di query simili a limit(). Ad esempio, per ottenere il numero di dipendenti assunti nel 2021:

  1. from datetime import date
  2. hired_in_2021_count = Employee.query.filter(db.and_(Employee.hire_date >= date(year=2021, month=1, day=1), Employee.hire_date < date(year=2022, month=1, day=1))).order_by(Employee.age).count()
  3. print(hired_in_2021_count)
Output
3

Qui usi la stessa query che hai usato in precedenza per ottenere tutti i dipendenti assunti nel 2021. E usi il count() per recuperare il numero di voci, che è 3.

Hai ordinato, limitato e contato i risultati delle query in Flask-SQLAlchemy. Successivamente, imparerai come suddividere i risultati delle query in più pagine e come creare un sistema di paginazione nelle tue applicazioni Flask.

Passaggio 5 — Visualizzazione di lunghe liste di record su più pagine

In questo passaggio, modificherai il percorso principale per fare in modo che la pagina di indice visualizzi i dipendenti su più pagine per rendere più facile la navigazione nell’elenco dei dipendenti.

Prima di tutto, utilizzerai la shell Flask per vedere una dimostrazione di come utilizzare la funzione di paginazione in Flask-SQLAlchemy. Apri la shell Flask se non l’hai già fatto:

  1. flask shell

Diciamo che vuoi dividere i record dei dipendenti nella tua tabella in più pagine, con due elementi per pagina. Puoi farlo utilizzando il metodo di query paginate() in questo modo:

  1. page1 = Employee.query.paginate(page=1, per_page=2)
  2. print(page1)
  3. print(page1.items)
Output
<flask_sqlalchemy.Pagination object at 0x7f1dbee7af80> [<Employee John Doe>, <Employee Mary Doe>]

Utilizzi il parametro page del metodo di query paginate() per specificare la pagina che desideri accedere, che è la prima pagina in questo caso. Il parametro per_page specifica il numero di elementi che ogni pagina deve avere. In questo caso lo imposti su 2 per fare in modo che ogni pagina abbia due elementi.

La variabile page1 qui è un oggetto di paginazione, che ti dà accesso agli attributi e ai metodi che utilizzerai per gestire la tua paginazione.

Accedi agli elementi della pagina utilizzando l’attributo items.

Per accedere alla pagina successiva, puoi utilizzare il metodo next() dell’oggetto di paginazione in questo modo, il risultato restituito è anche un oggetto di paginazione:

  1. page2 = page1.next()
  2. print(page2.items)
  3. print(page2)
Output
[<Employee Jane Tanaka>, <Employee Alex Brown>] <flask_sqlalchemy.Pagination object at 0x7f1dbee799c0>

Puoi ottenere un oggetto di paginazione per la pagina precedente utilizzando il metodo prev(). Nell’esempio seguente accedi all’oggetto di paginazione per la quarta pagina, quindi accedi all’oggetto di paginazione della sua pagina precedente, che è la pagina 3:

  1. page4 = Employee.query.paginate(page=4, per_page=2)
  2. print(page4.items)
  3. page3 = page4.prev()
  4. print(page3.items)
Output
[<Employee Scarlett Winter>, <Employee Emily Vill>] [<Employee James White>, <Employee Harold Ishida>]

Puoi accedere al numero di pagina corrente utilizzando l’attributo page in questo modo:

  1. print(page1.page)
  2. print(page2.page)
Output
1 2

Per ottenere il numero totale di pagine, utilizza l’attributo pages dell’oggetto di paginazione. Nell’esempio seguente, sia page1.pages che page2.pages restituiscono lo stesso valore perché il numero totale di pagine è costante:

  1. print(page1.pages)
  2. print(page2.pages)
Output
5 5

Per il numero totale di elementi, utilizza l’attributo total dell’oggetto di paginazione:

  1. print(page1.total)
  2. print(page2.total)
Output
9 9

Qui, poiché si interrogano tutti i dipendenti, il numero totale di elementi nella paginazione è 9, perché ci sono nove dipendenti nel database.

Ecco alcuni degli altri attributi che hanno gli oggetti di paginazione:

  • prev_num: Il numero di pagina precedente.
  • next_num: Il numero di pagina successivo.
  • has_next: True se c’è una pagina successiva.
  • has_prev: True se c’è una pagina precedente.
  • per_page: Il numero di elementi per pagina.

L’oggetto di paginazione ha anche un metodo iter_pages() che puoi ciclare per accedere ai numeri di pagina. Ad esempio, puoi stampare tutti i numeri di pagina in questo modo:

  1. pagination = Employee.query.paginate(page=1, per_page=2)
  2. for page_num in pagination.iter_pages():
  3. print(page_num)
Output
1 2 3 4 5

Quanto segue è una dimostrazione di come accedere a tutte le pagine e ai loro elementi utilizzando un oggetto di paginazione e il metodo iter_pages():

  1. pagination = Employee.query.paginate(page=1, per_page=2)
  2. for page_num in pagination.iter_pages():
  3. print('PAGE', pagination.page)
  4. print('-')
  5. print(pagination.items)
  6. print('-'*20)
  7. pagination = pagination.next()
Output
PAGE 1 - [<Employee John Doe>, <Employee Mary Doe>] -------------------- PAGE 2 - [<Employee Jane Tanaka>, <Employee Alex Brown>] -------------------- PAGE 3 - [<Employee James White>, <Employee Harold Ishida>] -------------------- PAGE 4 - [<Employee Scarlett Winter>, <Employee Emily Vill>] -------------------- PAGE 5 - [<Employee Mary Park>] --------------------

Qui, crei un oggetto di paginazione che parte dalla prima pagina. Cicli attraverso le pagine usando un ciclo for con il metodo di paginazione iter_pages(). Stampa il numero di pagina e gli elementi di pagina, e imposti l’oggetto pagination sull’oggetto di paginazione della sua pagina successiva utilizzando il metodo next().

È possibile utilizzare anche i metodi filter() e order_by() con il metodo paginate() per paginare i risultati delle query filtrate e ordinati. Ad esempio, è possibile ottenere dipendenti di età superiore ai trent’anni e ordinare i risultati per età e paginare i risultati in questo modo:

  1. pagination = Employee.query.filter(Employee.age > 30).order_by(Employee.age).paginate(page=1, per_page=2)
  2. for page_num in pagination.iter_pages():
  3. print('PAGE', pagination.page)
  4. print('-')
  5. for employee in pagination.items:
  6. print(employee, '| Age: ', employee.age)
  7. print('-'*20)
  8. pagination = pagination.next()
Output
PAGE 1 - <Employee John Doe> | Age: 32 <Employee Jane Tanaka> | Age: 32 -------------------- PAGE 2 - <Employee Mary Doe> | Age: 38 <Employee Harold Ishida> | Age: 52 --------------------

Ora che hai una solida comprensione di come funziona la paginazione in Flask-SQLAlchemy, modificherai la pagina principale della tua applicazione per visualizzare i dipendenti su più pagine per una navigazione più semplice.

Esci dalla shell di Flask:

  1. exit()

Per accedere a diverse pagine, userai parametri URL, noti anche come stringhe di query URL, che sono un modo per passare informazioni all’applicazione attraverso l’URL. I parametri vengono passati all’applicazione nell’URL dopo un simbolo ?. Ad esempio, per passare un parametro page con valori diversi, è possibile utilizzare i seguenti URL:

http://127.0.0.1:5000/?page=1
http://127.0.0.1:5000/?page=3

Qui, il primo URL passa il valore 1 al parametro URL page. Il secondo URL passa il valore 3 allo stesso parametro.

Apri il file app.py:

  1. nano app.py

Modifica il percorso dell’indice come segue:

@app.route('/')
def index():
    page = request.args.get('page', 1, type=int)
    pagination = Employee.query.order_by(Employee.firstname).paginate(
        page, per_page=2)
    return render_template('index.html', pagination=pagination)

Qui, si ottiene il valore del parametro URL page utilizzando l’oggetto request.args e il suo metodo get(). Ad esempio, /?page=1 otterrà il valore 1 dal parametro URL page. Si passa 1 come valore predefinito, e si passa il tipo Python int come argomento al parametro type per assicurarsi che il valore sia un intero.

Successivamente crei un oggetto pagination, ordinando i risultati della query per nome. Passi il valore del parametro URL page al metodo paginate(), e suddividi i risultati in due elementi per pagina passando il valore 2 al parametro per_page.

Infine, passi l’oggetto pagination che hai costruito al template index.html renderizzato.

Salva e chiudi il file.

Successivamente, modifica il template index.html per visualizzare gli elementi di paginazione:

  1. nano templates/index.html

Modifica il tag div del contenuto aggiungendo un’intestazione h2 che indica la pagina corrente, e modifica il ciclo for per iterare sull’oggetto pagination.items invece dell’oggetto employees, che non è più disponibile:

<div class="content">
    <h2>(Page {{ pagination.page }})</h2>
    {% for employee in pagination.items %}
        <div class="employee">
            <p><b>#{{ employee.id }}</b></p>
            <b>
                <p class="name">{{ employee.firstname }} {{ employee.lastname }}</p>
            </b>
            <p>{{ employee.email }}</p>
            <p>{{ employee.age }} years old.</p>
            <p>Hired: {{ employee.hire_date }}</p>
            {% if employee.active %}
                <p><i>(Active)</i></p>
            {% else %}
                <p><i>(Out of Office)</i></p>
            {% endif %}
        </div>
    {% endfor %}
</div>

Salva e chiudi il file.

Se non l’hai già fatto, imposta le variabili d’ambiente FLASK_APP e FLASK_ENV e avvia il server di sviluppo:

  1. export FLASK_APP=app
  2. export FLASK_ENV=development
  3. flask run

Ora, naviga alla pagina indice con valori diversi per il parametro URL page:

http://127.0.0.1:5000/
http://127.0.0.1:5000/?page=2
http://127.0.0.1:5000/?page=4
http://127.0.0.1:5000/?page=19

Vedrai pagine diverse con due elementi ciascuna, e elementi diversi in ogni pagina, come hai già visto in precedenza nella shell di Flask.

Se il numero di pagina fornito non esiste, otterrai un errore HTTP 404 Not Found, come nel caso dell’ultimo URL nell’elenco URL precedente.

Successivamente, creerai un widget di paginazione per navigare tra le pagine. Utilizzerai alcuni attributi e metodi dell’oggetto di paginazione per visualizzare tutti i numeri di pagina, ciascun numero sarà collegato alla sua pagina dedicata, e un pulsante <<< per tornare indietro se la pagina corrente ha una pagina precedente, e un pulsante >>> per passare alla pagina successiva se esiste.

Il widget di paginazione avrà il seguente aspetto:


Per aggiungerlo, apri index.html:

  1. nano templates/index.html

Modifica il file aggiungendo il seguente div evidenziato sotto il div del contenuto:

flask_app/templates/index.html
<div class="content">
    {% for employee in pagination.items %}
        <div class="employee">
            <p><b>#{{ employee.id }}</b></p>
            <b>
                <p class="name">{{ employee.firstname }} {{ employee.lastname }}</p>
            </b>
            <p>{{ employee.email }}</p>
            <p>{{ employee.age }} years old.</p>
            <p>Hired: {{ employee.hire_date }}</p>
            {% if employee.active %}
                <p><i>(Active)</i></p>
            {% else %}
                <p><i>(Out of Office)</i></p>
            {% endif %}
        </div>
    {% endfor %}
</div>

<div class="pagination">
    {% if pagination.has_prev %}
        <span>
            <a class='page-number' href="{{ url_for('index', page=pagination.prev_num) }}">
                {{ '<<<' }}
            </a>
        </span>
    {% endif %}

    {% for number in pagination.iter_pages() %}
        {% if pagination.page != number %}
            <span>
                    <a class='page-number'
                        href="{{ url_for('index', page=number) }}">
                    {{ number }}
                    </a>
            </span>
        {% else %}
            <span class='current-page-number'>{{ number }}</span>
        {% endif %}
    {% endfor %}

    {% if pagination.has_next %}
        <span>
            <a class='page-number'
                href="{{ url_for('index', page=pagination.next_num) }}">
                {{ '>>>' }}
            </a>
        </span>
    {% endif %}
</div>

Salva e chiudi il file.

Qui, utilizzi la condizione if pagination.has_prev per aggiungere un collegamento <<< alla pagina precedente se la pagina corrente non è la prima pagina. Collegati alla pagina precedente utilizzando la chiamata di funzione url_for('index', page=pagination.prev_num), nella quale ti colleghi alla funzione di visualizzazione dell’indice, passando il valore pagination.prev_num al parametro URL page.

Per visualizzare i collegamenti a tutti i numeri di pagina disponibili, fai un loop sugli elementi del metodo pagination.iter_pages() che ti fornisce un numero di pagina in ogni iterazione.

Usi la condizione if pagination.page != number per verificare se il numero della pagina corrente non è lo stesso del numero nel ciclo corrente. Se la condizione è vera, collegati alla pagina per consentire all’utente di cambiare la pagina corrente con un’altra pagina. In caso contrario, se la pagina corrente è la stessa del numero del ciclo, visualizzi il numero senza un collegamento. Questo consente agli utenti di conoscere il numero della pagina corrente nel widget di paginazione.

Infine, usi la condizione pagination.has_next per verificare se la pagina corrente ha una pagina successiva, nel qual caso ti colleghi ad essa utilizzando la chiamata url_for('index', page=pagination.next_num) e un collegamento >>>.

Naviga alla pagina di indice nel tuo browser: http://127.0.0.1:5000/

Vedrai che il widget di paginazione è completamente funzionale:


Qui, usi >>> per passare alla pagina successiva e <<< per la pagina precedente, ma puoi anche utilizzare altri caratteri che preferisci, come > e < o immagini nei tag <img>.

Hai visualizzato dipendenti su più pagine e imparato come gestire la paginazione in Flask-SQLAlchemy. Ora puoi utilizzare il tuo widget di paginazione su altre applicazioni Flask che sviluppi.

Conclusione

Hai utilizzato Flask-SQLAlchemy per creare un sistema di gestione dipendenti. Hai interrogato una tabella e filtrato i risultati in base ai valori delle colonne e a condizioni logiche semplici e complesse. Hai ordinato, contato e limitato i risultati della query. E hai creato un sistema di paginazione per visualizzare un certo numero di record su ogni pagina nella tua applicazione web e navigare tra le pagine.

Puoi utilizzare ciò che hai imparato in questo tutorial in combinazione con i concetti spiegati in alcuni dei nostri altri tutorial su Flask-SQLAlchemy per aggiungere più funzionalità al tuo sistema di gestione dipendenti:

Se desideri leggere ulteriori informazioni su Flask, dai un’occhiata agli altri tutorial della serie Come costruire applicazioni web con Flask.

Source:
https://www.digitalocean.com/community/tutorials/how-to-query-tables-and-paginate-data-in-flask-sqlalchemy