[PYTHON] Versuchen Sie, eine einfache Website mit Responder und sqlite3 zu erstellen

Kürzlich habe ich ein Buch mit dem Titel "Make with Nuxt.js and Python! Einführung in die schleimige Entwicklung von KI-Anwendungen" gelesen, und das Buch ist ein ziemlich neues Python-Web. Da der Framework-Responder eingeführt wird, möchte ich eine einfache Website erstellen, nachdem ich verschiedene Dinge mit Interesse studiert habe.

Die Zielsite ist diesmal eine Site, an der Sie eine Verbindung zu einer SQL-Datenbank herstellen können, um Daten anzuzeigen, hinzuzufügen, zu aktualisieren und zu löschen.

Die Datenbank verwendet sqlite3, was am einfachsten ist.

Über das zu verwendende Modul

Neben dem Buch habe ich verschiedene Artikel über die Verwendung von Responder und sqlite3 gelesen.

responder

sqlite3

Diese Artikel waren sehr hilfreich, daher werde ich hier auf die grundlegende Verwendung verzichten.

Konstruktion

Vorbereitung

Die Datenbank sollte der Einfachheit halber SQLite sein.

SQLite ist beim Erstellen einer tatsächlichen Site nicht sehr geeignet, aber im Gegensatz zu MySQL und PostgreSQL muss SQLite nicht installiert werden und ist praktisch, da es von Anfang an enthalten ist.

Die einzigen verwendeten Python-Module sind hauptsächlich Responder und SQLite3.

sqlite3 ist ein Standard-Python-Modul. Sie müssen also nur den Responder installieren.

Offizielle Website des Responders sagt, dass pipenv verwendet werden soll, aber Sie können es problemlos mit einem normalen Pip installieren.

pip install responder

Funktion

Erstellen Sie eine einfache Website wie diese.

Datenbank

Spaltenname Datentyp
Name namae text
Niveau lv integer

Dieses Mal möchte ich nur sicherstellen, dass ich eine Verbindung zur Datenbank herstellen und mit ihr interagieren kann. Der Einfachheit halber mache ich daraus eine Tabelle mit nur zwei Spalten.

Wenn diese Tabelle SQL-Code ist

create table kyara (namae text,lv integer, primary key (namae))

Datei

Die Seite besteht nur aus diesen 5 Dateien.

截屏2020-05-19-19.42.03.png

Die HTML-Datei ist eine jinja2-Vorlage. Ich habe jinja2 noch nie benutzt, aber es ist ein bisschen wie die Django-Vorlage.

Wie Sie sehen, lautet der Name der Datei übrigens " [Eine bestimmte magische verbotene Liste](https://ja.wikipedia.org/wiki/ Eine bestimmte magische verbotene Liste) ".

│- majutsu.Ausführbarer Code des py-Servers
│─ index.HTML-Indexseite
│- toaru.HTML-Datenanzeige und Bearbeitungsseite
│- no.HTML-Seite, die angezeigt wird, wenn etwas nicht stimmt
└─ librorum
   └─prohibitorum.CSS-Stylesheet

Umgebung

Ich denke, dass es nicht viel Problem gibt, auch wenn das Betriebssystem und die Versionen von Python und Responder unterschiedlich sind, aber ich werde die Umgebung schreiben, wenn ich es diesmal versuche.

--Mac OS 10.15.4 [Catalina](https://ja.wikipedia.org/wiki/ Ich bin als Bösewichtstochter wiedergeboren worden, die nur die Ruinenflagge des ersten Spiels hat ...)

Code

Als nächstes folgt eine Beschreibung des Codes in jeder Datei.

HTML-Vorlage

HTML-Datei der Jinja2-Vorlage

index.html

Zuerst die Indexseite.

<head>
    <meta charset="utf-8">
    <title>INDEX einer bestimmten Site</title>
    <link rel="stylesheet" href="/librorum/prohibitorum.css" type="text/css" media="all">
</head>

<body>
    <h3>Ein bestimmter sqlite3-Responder</h3>
    <ul>
        {% for k in kyara %}
        <li>
            <a href="/toaru/{{ k[0] }}">{{ k[0] }}</a> lv {{ k[1] }}
        </li>
        {% endfor %}
    </ul>

    <form action="/insert" method="post">
        <div>Name<input type="text" name="namae"></div>
        <div>Niveau<input type="text" name="lv"><br></div>
        <div><input type="submit" value="hinzufügen"></div>
    </form>

    <a href="/download">herunterladen</a>
</body>

Die Zusammensetzung ist --Datenaufzählung --Form, um neue Daten hinzuzufügen-

toaru.html

Als nächstes sehen Sie eine Seite zum Anzeigen und Bearbeiten der Daten eines bestimmten Zeichens.

<head>
    <meta charset="utf-8">
    <title>ein{{ namae }}Seite von</title>
    <link rel="stylesheet" href="/librorum/prohibitorum.css" type="text/css" media="all">
</head>

<body>
    <form action="/update/{{ namae }}" method="post">
        <div>Name: <input type="text" name="namae" value="{{ namae }}"></div>
        <div>Niveau: <input type="text" name="lv" value="{{ lv }}"></div>
        <input type="submit" value="aktualisieren">
    </form>

    <form action="/delete/{{ namae }}" method="delete">
        <input type="submit" value="Löschen">
    </form>
    
    <div><a href="/">Rückkehr</a></div>
</body>

Die Zusammensetzung ist

no.html

Und die Seite, die angezeigt wird, wenn etwas schief geht. Es gibt nur einen Link zurück zum Index.

<head>
    <meta charset="utf-8">
</head>

<body>
    <h1>NO!!</h1>
Der Himmel ist so blau, aber die Spitze ist pechschwarz<br><br>
    <a href="/">~-Rückkehr-~</a>
</body>

python

* Eine Datei, die mithilfe von Magie alles auf der * </ s> -Site steuert.

Wenn es sich um eine große Site handelt, muss sie möglicherweise in verschiedene Dateien zerlegt werden. Diesmal handelt es sich jedoch um eine kleine Site, sodass es nicht erforderlich ist, sie in eine Datei zu trennen.

Die Controller für alle Routen und den gesamten Code, der eine Verbindung zur Datenbank herstellt, finden Sie hier.

majutsu.py

import responder,sqlite3,urllib,os

#Datei zum Speichern von Daten
dbfile = 'dedicatus545.db'
#API-Objekt
api = responder.API(templates_dir='.', #Vorlagenordner
                    static_dir='librorum', #Statischer Dateiordner
                    static_route='/librorum') #Statisches Dateistammverzeichnis

#Indexseite
@api.route('/')
def index(req,resp):
    with sqlite3.connect(dbfile) as conn:
        sql_select = '''
            select * from kyara
        ''' #Daten aller Zeichen anzeigen
        kyara = conn.execute(sql_select).fetchall()
        resp.html = api.template('index.html',kyara=kyara)

#Jede Datenanzeige- und Bearbeitungsseite
@api.route('/toaru/{namae}')
def select(req,resp,*,namae):
    with sqlite3.connect(dbfile) as conn:
        sql_select = '''
            select * from kyara where namae==?
        ''' #Nimm die Daten des Charakters mit diesem Namen
        kyara = conn.execute(sql_select,[namae]).fetchone()
        if(kyara):
            resp.html = api.template('toaru.html',namae=kyara[0],lv=kyara[1])
        else:
            print('Diese Seite existiert nicht')
            api.redirect(resp,'/no') #Wenn ein nicht vorhandener Name eingegeben wird, wechseln Sie zur Fehlerseite
    
#Seite, wenn etwas schief geht
@api.route('/no')
def no(req,resp):
    resp.html = api.template('no.html')

#Nach dem Hinzufügen von Daten
@api.route('/insert')
async def insert(req,resp):
    try:
        with sqlite3.connect(dbfile) as conn:
            param = await req.media() #Daten aus dem Formular abrufen
            namae = param['namae']
            lv = param['lv']
            sql_insert = '''
                insert into kyara (namae,lv)
                values (?,?)
            ''' #Neue Daten hinzufügen
            conn.execute(sql_insert,(namae,lv))
        api.redirect(resp,'/') #Zurück zur Indexseite
    except Exception as err:
        print(f'Error: {type(err)} {err}')
        api.redirect(resp,'/no') #Wenn etwas schief läuft

#Nach dem Aktualisieren der Daten
@api.route('/update/{namae0}')
async def update(req,resp,*,namae0):
    try:
        with sqlite3.connect(dbfile) as conn:
            param = await req.media() #Daten aus dem Formular abrufen
            namae = param['namae']
            lv = param['lv']
            
            sql_update = '''
                update kyara set namae=?,lv=? where namae==?
            ''' #Datenaktualisierung
            conn.execute(sql_update,(namae,lv,namae0))
        #Zurück zur Datenanzeigeseite**Wenn Sie dem Namen hier nicht entkommen, wird möglicherweise eine Fehlermeldung angezeigt, also urllib.parse.brauche ein Angebot
        api.redirect(resp,f'/toaru/{urllib.parse.quote(namae)}')
    except Exception as err:
        print(f'Error: {type(err)} {err}')
        api.redirect(resp,'/no') #Wenn etwas nicht stimmt

#Nach dem Löschen der Daten
@api.route('/delete/{namae}')
def delete(req,resp,*,namae):
    try:
        with sqlite3.connect(dbfile) as conn:
            sql_delete = '''
                delete from kyara where namae==?
            ''' #Daten löschen
            conn.execute(sql_delete,[namae])
        api.redirect(resp,'/') #Zurück zur Indexseite
    except Exception as err:
        print(f'Error: {type(err)} {err}')
        api.redirect(resp,'/no') #Wenn etwas schief läuft

#Lade Daten
@api.route('/download')
def download(req,resp):
    with sqlite3.connect(dbfile) as conn:
        #Daten in JSON-Datei
        data = conn.execute('select * from kyara').fetchall()
        resp.media = [{'namae': d[0], 'lv': d[1]} for d in data]
        #Geben Sie in der Kopfzeile an, dass die Seite zum Herunterladen der Datei erstellt werden soll
        resp.headers['Content-Disposition'] = 'attachment; filename=data.json'



if(__name__=='__main__'):
    #Erstellen Sie eine neue Tabelle, wenn Sie sie zum ersten Mal ausführen
    if(not os.path.exists(dbfile)):
        with sqlite3.connect(dbfile) as conn:
            sql_create = '''
                create table kyara (
                    namae text,
                    lv integer,
                    primary key (namae)
                )
            '''
            conn.execute(sql_create)
    
    #Serverstart
    api.run()

Es gibt 7 Routen, aber ich benutze tatsächlich die Vorlage

  • '/'
  • '/toaru/{namae}'
  • '/no'

Nur drei.

Darüber hinaus

  • '/insert'
  • '/update/{namae0}'
  • '/delete/{namae}'

Sie interagieren mit der Datenbank und leiten auf andere Seiten weiter.

Die Seiten ** '/ insert' ** und ** '/ update / {namae0}' ** sind asynchrone Funktionen, da sie Daten aus dem Formular empfangen und warten müssen.

Ich habe gerade etwas über Async gelernt und warte kürzlich in Python. Ich habe verschiedene Qiita-Artikel gelesen und es war hilfreich, deshalb werde ich es hier vorstellen

Wenn Sie den Responder verwenden, ist es sehr nützlich, die asynchrone Verarbeitung zu verstehen, auch wenn wir nicht asynchron schreiben und direkt warten, da es viele Funktionen gibt, die mit asynchron arbeiten und in erster Linie auf den Responder warten.

Schließlich ist ** '/ download' ** eine Seite zum Speichern aller Daten in der Datenbank in einer JSON-Datei.

Die Datenbank wird beim ersten Ausführen des Servers erstellt. Danach wird eine Datei mit der Datenbank (hier dedicatus545.db) angezeigt.

Das responder.API-Objekt wird wie folgt festgelegt

templates_dir = '.'
static_dir    = 'librorum'
static_route  = '/librorum'

templates_dir ist der Ordner mit den Vorlagen. Standardmäßig befindet es sich in einem Ordner namens "Vorlagen". Dieses Mal wird der Ordner jedoch nicht verwendet. Geben Sie ihn daher als "." An.

static_dir ist der Ordner, der die statischen Dateien enthält. Der Standardordner ist statisch, aber hier ist es "Librorum".

static_route ist das Stammverzeichnis der statischen Datei, die standardmäßig '/ static' ist, aber auch '/ librorum' sein sollte.

css

Website-Dekoration ist nicht der Hauptzweck dieser Zeit, daher CSS geeignet genug, um ein kleines Spektakel zu sein

librorum/prohibitorum.css

div,li,h3 {
    padding: 2px;
    font-size: 20px;
}
input {
    border: solid #194 2px;
    font-size: 19px;
}
form {
    margin: 3;
}

Ausführung und Ergebnisse

Sobald der Code fertig ist, ist es Zeit, den .py-Code des Servers auszuführen.

python majutsu.py

Greifen Sie dann mit Ihrem Browser auf http://127.0.0.1:5042/ zu.

Hier werden wir mit Firefox gehen.

Wenn es keine Fehler gibt, sollten Sie eine Seite wie diese sehen.

q01.png

Da noch keine Daten vorhanden sind, fügen wir sie zuerst hinzu.

q02.png

Geben Sie einen Namen und eine Ebene ein und klicken Sie auf die Schaltfläche Hinzufügen, um die Daten hinzuzufügen. Fügen Sie einen weiteren hinzu, um es zu versuchen.

q03.png

q04.png

Klicken Sie auf den Link "Download" und die Daten werden als JSON-Datei heruntergeladen.

q05.png

Wenn diese Methode verwendet wird, ist das Kanji bei der Konvertierung in json jedoch wie folgt Unicode.

[{"namae": "\u4e0a\u6761\u5f53\u9ebb", "lv": 0}, {"namae": "\u5fa1\u5742\u7f8e\u7434", "lv": 5}]

Wie Sie dies vermeiden können, finden Sie in diesem Artikel unter https://qiita.com/nassy20/items/adc59c4b7abd202dda26

Trotzdem, als ich es mit Firefox nachgeschlagen habe, kehrte es richtig zu Kanji zurück, also denke ich, dass es diesmal in Ordnung ist.

q06.png

Wenn Sie als Nächstes versuchen, auf die Schaltfläche Hinzufügen zu klicken, ohne das Formular auszufüllen, tritt ein Fehler auf und Sie werden zu dieser Seite weitergeleitet. q07.png

Die Fehlerursache ist, dass bei Verwendung von req.media (), da der Name nicht eingegeben wurde, der Aufruf von param ['namae'] ohne den Schlüssel 'namae' zu einem Fehler führt.

Es ist besser, .get () zu verwenden, um den Fehler zu vermeiden, aber dieses Mal muss es nicht an erster Stelle leer sein, damit Sie es so lassen können, wie es hier ist.

Gehen Sie zurück zum Index, klicken Sie auf einen Namen und geben Sie den Link ein, um zur Datenbearbeitungsseite zu gelangen.

q08.png

Wenn ich versuche, die Ebene zu leeren und auf die Schaltfläche "Aktualisieren" zu klicken, wird ein Fehler angezeigt und ich gehe erneut zur Seite "Nein".

Wenn Sie erneut zu dieser Seite zurückkehren, geben Sie diesmal neue Daten ein und klicken Sie auf die Schaltfläche. Die Daten werden aktualisiert.

Wenn Sie zum Index zurückkehren, können Sie bestätigen, dass die Daten ordnungsgemäß aktualisiert wurden.

q09.png

Wenn Sie die Bearbeitungsseite erneut aufrufen und auf die Schaltfläche Löschen klicken

q10.png

Diese Daten werden verschwinden.

q11.png

Damit ist der Test aller Funktionen abgeschlossen.

Am Ende

So wurde die Website mit Responder und sqlite3 erstellt.

Es ist vielleicht nur eine einfache und unbrauchbare Website, aber ich denke, sie kann als grundlegende Methode zum Erstellen einer vollwertigen Website verwendet werden.

Ein Beispiel für das Hinzufügen von Javascript usw. zur Erstellung von SPA finden Sie im nächsten Artikel >> https://qiita.com/phyblas/items/f3f40df76f85d61d5286

Recommended Posts

Versuchen Sie, eine einfache Website mit Responder und sqlite3 zu erstellen
Erstellen Sie eine Drohnen-Simulator-Umgebung und versuchen Sie einen einfachen Flug mit Mission Planner
Versuchen Sie, ein einfaches Spiel mit Python 3 und iPhone zu erstellen
Versuchen Sie, mit einer Shell zu programmieren!
Probieren Sie Amazon Simple Workflow Service (SWF) mit Python und boto3 aus
Ein einfacher interaktiver Musikplayer mit Chuck und OpenPose
Versuchen Sie, ein Unterfenster mit PyQt5 und Python zu öffnen
(Für Anfänger) Versuchen Sie, mit Django eine einfache Web-API zu erstellen
Ich habe eine einfache Schaltung mit Python gemacht (AND, OR, NOR, etc.)
Erstellen Sie mit Python und OpenCV ein einfaches OMR (Mark Sheet Reader)
Rails-Benutzer versuchen, mit Django eine einfache Blog-Engine zu erstellen
Einführung und Verwendung der Python-Flasche ・ Versuchen Sie, einen einfachen Webserver mit Anmeldefunktion einzurichten
SDN-Grundkurs für Programmierer 3: Erstellen Sie mit Ryu einen Switching Hub
Erstellen Sie mit Raspberry Pi einen WLAN-Ethernet-Konverter und einen einfachen Router
Die Geschichte einer Soundkamera mit Touch Designer und ReSpeaker
Erstellen einer einfachen Power-Datei mit Python
Einfacher RSS-Reader mit Django
Versuchen Sie, eine einfache Animation in Python zu zeichnen
Versuchen Sie, mit matplotlib eine Normalverteilung zu zeichnen
Ein Memo mit Python2.7 und Python3 in CentOS
Versuchen wir es mit gRPC mit Go und Docker
Lassen Sie uns mit PLY 1 eine einfache Sprache erstellen
Erstellen Sie eine einfache Web-App mit Flasche
Versuchen Sie HTML-Scraping mit der Python-Bibliothek
Versuchen Sie, eine Karte mit Python + Cartopy 0.18.0 zu zeichnen
Implementieren Sie ein Modell mit Status und Verhalten
Veröffentlichen Sie Ihre Website mit Responder + Gunicorn + Apache
Ich habe mit Python einen einfachen Blackjack gemacht
Probieren Sie TensorFlows RNN mit einem Basismodell aus
Stellen Sie Docker in Windows Home und führen Sie einen einfachen Webserver mit Python aus
Eine einfache Problemumgehung für Bots, um zu versuchen, Tweets mit demselben Inhalt zu veröffentlichen
Erstellen wir ein einfaches Empfangssystem mit dem serverlosen Python-Framework Chalice und Twilio
WEB Scraping mit Python und versuchen, aus Bewertungen eine Wortwolke zu machen
Versuchen Sie, eine Webanwendung mit Vue.js und Django (Mac Edition) zu erstellen - (1) Umgebungskonstruktion, Anwendungserstellung
Ich habe versucht, eine einfache Bilderkennungs-API mit Fast API und Tensorflow zu erstellen
Richten Sie einen einfachen HTTPS-Server mit Asyncio ein
Verbinden Sie Scratch X und Digispark mit der Flasche
Versuchen Sie Tensorflow mit einer GPU-Instanz unter AWS
Erstellen einer Python-Umgebung mit virtualenv und direnv
Versuchen Sie, Google Chrome mit Python und Selenium auszuführen
Erstellen Sie mit Flask einen einfachen Punktbildgenerator
Versuchen Sie, mit Python eine Lebenskurve zu zeichnen
Versuchen Sie, eine Nachricht mit dem SMS-Dienst von Twilio zu senden
Starten Sie mit Docker einen einfachen Python-Webserver
Versuche mit EV3 und PC zu kommunizieren! (MQTT)
Versuchen Sie, in Python einen "Entschlüsselungs" -Code zu erstellen
Ich habe eine einfache Brieftasche aus Bitcoin mit Pycoin gemacht
Erstellen Sie eine virtuelle Umgebung mit pyenv und venv
Starten Sie einen Webserver mit Python und Flask
Kompilieren Sie Rust und führen Sie es mit einem einzigen Befehl aus
Versuchen Sie, mit Python eine Diedergruppe zu bilden
Einfache Aufgabenliste, erstellt mit Python + Django
Versuchen Sie, eine Karte mit Pythons Folium-Paket zu zeichnen
Versuchen Sie, ein FizzBuzz-Problem mit einem Shell-Programm zu erstellen
Ich habe versucht, die Datenbank (sqlite3) mit kivy zu verwenden
Entwickeln Sie eine Web-API, die in DB gespeicherte Daten mit Django und SQLite zurückgibt
Holen Sie sich mit Python eine große Menge von Starbas Twitter-Daten und probieren Sie die Datenanalyse Teil 1 aus