Flask - 'Post'-Methode

Django, Flask, Bottle, WSGI, CGI…
Antworten
headhunter1978
User
Beiträge: 20
Registriert: Sonntag 18. November 2018, 11:15

Hallo zusammen,

ich habe folgende Problem:

Ich will ein kleines Tool mit Flask und sqlite realisieren. Es handelt sich dabei um eine ToDo-App, die ich später noch erweitern möchte.
  • Mit der form.html möchte ich die Eingaben für die Datenbank machen.
    Mit der index.html werden alle Inhalte aus der Datenbank dargestellt.
Ich habe das Problem, dass ich über das Formular aus form.html keine Daten in die Datenbank schreiben kann. Es wird Http 405-Fehler werden ausgelöst, was zeigt, dass wenn eine HTTP-Methode von einem Webserver für eine angeforderte URL nicht zulässig ist. Wenn ich in der app.py die Zeile @app.route('/') nach @app.route('/', methods=['POST', 'GET']) ändere (grundsätzlich macht mir diese Änderung keinen Sinn), bekomme ich keine Fehler mehr, aber es werden auch keine Daten in die Datenbank geschrieben.

Anmerkungen.
  • Die Datenbank habe ich manuell angelegt.
    Ich kann auch manuell Daten in Datenbank ablegen.
    Die Daten werden über die Tabelle aus index.html auch aus gegeben.
app.py

Code: Alles auswählen

from flask import Flask, render_template, url_for, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///test.db'
# URI = Uniform Request Identifier
# /// relative path vs. //// direct path
db  = SQLAlchemy(app)

class ToDo(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(200), nullable = False)
    date_created = db.Column(db.DateTime, default = datetime.utcnow)

    def __repr__(self):
        return '<Task %r>' % self.id

@app.route('/')
def index():

    tasks = ToDo.query.order_by(ToDo.date_created).all()
    return render_template('index.html', tasks=tasks)

@app.route('/form', methods=['POST', 'GET'])
def form():
    if request.method == 'POST':
        task_content = request.form['content']
        new_task = ToDo(content=task_content)

        try:
            db.session.add(new_task)
            db.session.commit()
            return redirect('/')
        except:
            return 'There was an issue adding your task'

    else:
        
        return render_template('form.html')

@app.route('/delete/<int:id>')
def delete(id):
    task_to_delete = ToDo.query.get_or_404(id)

    try:
        db.session.delete(task_to_delete)
        db.session.commit()
        return redirect('/')
    except:
        return 'There was an issue deleteing that task'

@app.route('/update/<int:id>', methods=['POST', 'GET'])
def update(id):
    task = ToDo.query.get_or_404(id)

    if request.method == 'POST':
        task.content = request.form['content']

        try:
            db.session.commit()
            return redirect('/')
        except:
            return 'There was an issue updating your task'

    else:
        return render_template('update.html', task=task)

if __name__ == '__main__':
    app.run(debug=True)
index.html

Code: Alles auswählen

{% extends 'base.html' %}

{% block head %} 

    <title>Task Master</title>

{% endblock %}

{% block body %} 

<div class = "content">
    <h1>Task Master</h1>
    <table>
        <tr>
            <th>Task</th>
            <th>Added</th>
            <th>Action</th>
        </tr>

        {% for task in tasks %}
        <tr>
            <td>{{task.content}}</td>
            <td>{{task.date_created.date()}}</td>
            <td>
                <a href ="/delete/{{task.id}}">Delete</a>
                <br>
                <a href ="/update/{{task.id}}">Update</a>
            </td>
        </tr>
        {% endfor %}
    </table>
    
</div>

{% endblock %}
form.html

Code: Alles auswählen

{% extends 'base.html' %}

{% block head %} 

    <title>Task Master</title>

{% endblock %}

{% block body %} 

<div class = "content">
    <h1>Task Master</h1>

    <form action="/" method="POST">
        <input type="text" name="content" id="content" value="content">
        <input type ="submit" value="Add Task">
    </form>
</div>

{% endblock %}
Seht ihr, was ich falsch mache.
Benutzeravatar
__blackjack__
User
Beiträge: 13110
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@headhunter1978: Du möchtest über das `action` in ``<form action="/" method="POST">`` nachdenken. 😉
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
headhunter1978
User
Beiträge: 20
Registriert: Sonntag 18. November 2018, 11:15

ich sehe meinen Fehler nicht ...
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Was hat das action-Attribut für eine Bedeutung?
headhunter1978
User
Beiträge: 20
Registriert: Sonntag 18. November 2018, 11:15

Sirius3 hat geschrieben: Sonntag 21. Juni 2020, 13:01 Was hat das action-Attribut für eine Bedeutung?
eigentlich das Ziel ... Die index.html macht als Ziel in diesem Fall keinen Sinn, dort läuft später der Redirect in der app.py hin. Mir ist trotzdem nicht klar, was ich als Ziel dort hinterlege ...
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Da hast doch schon eine Route dafür in Deinem Python-Programm definiert, die mußt Du auch nehmen.
headhunter1978
User
Beiträge: 20
Registriert: Sonntag 18. November 2018, 11:15

Ich hatte einen Denkfehler in der app.py.

Code: Alles auswählen

@app.route('/', methods=['POST', 'GET'])
def index():

    if request.method == 'POST':
        task_content = request.form['content']
        new_task = ToDo(content=task_content)

        try:
            db.session.add(new_task)
            db.session.commit()
            return redirect('/')
        except:
            return 'There was an issue adding your task'

    else:
        tasks = ToDo.query.order_by(ToDo.date_created).all()
        return render_template('index.html', tasks=tasks)

@app.route('/form')
def form():
    return render_template('form.html')
Benutzeravatar
__blackjack__
User
Beiträge: 13110
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@headhunter1978: Was soll denn dort jetzt in "/" der „redirect“ auf "/"? Da bist Du doch schon. Der Code im ``else``-Zweig gehört da eher nicht hin sondern einfach bedingungslos ans Ende dieser Funktion.

Mit diese nacken ``except:``\s die nichtssagenden Text an den Benutzer ausliefern, in einer HTTP-Antwort die einen ”OK”-Status hat, solltest Du auch sorfort aufhören. Das ist so absolut gar keine sinnvolle Fehlerbehandlung, weil Du so Fehler untersdrückst und keine sinnvolle Möglichkeit mehr hast heraus zu finden *was* denn das Problem war. Wenn man nichts sinnvolles mit Ausnahmen anfangen kann, dann behandelt man die einfach gar nicht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten