flask: url_for funktioniert nicht

Django, Flask, Bottle, WSGI, CGI…
Antworten
Benutzeravatar
Domroon
User
Beiträge: 104
Registriert: Dienstag 3. November 2020, 10:27
Wohnort: Dortmund

Hallo Leute,

wahrscheinlich habe ich irgendwo einen Tippfehler oder irgendwas in einem falschen Pfad. Ich habe alles überprüft und verstehe es einfach nicht. Wenn ich in der "register()" Funktion "url_for('login')" aufrufe bekomme ich immer einen "jinja2.exceptions.TemplateNotFound" Fehler:

Vollständiges Projekt hier: https://github.com/Domroon/theurer_projekt

Hier routes.py:

Code: Alles auswählen

from werkzeug.utils import redirect
from flask_website.models import User, Question
from flask import request, flash, render_template, url_for
from flask_website import app, db, bcrypt


buttons = [
    {
        'title': 'Home',
        'link': 'home'
    },
    {
        'title': 'Klavierunterricht',
        'link': 'piano_lesson'
    },
    {
        'title': 'Schlagzeugunterricht',
        'link': 'drums_lesson'
    },
    {
        'title': 'Kontakt',
        'link': 'contact'
    }
]


def post_request():
    if request.method == 'POST':
        email = request.form['email']
        question = request.form['question']
        if not email:
            flash("Bitte gib eine Email-Adresse ein", 'danger')
        elif not question:
            flash("Bitte gib eine Frage ein", 'danger')
        else:
            question = Question(email=email, question=question)
            db.session.add(question)
            db.session.commit()
            flash("Frage erfolgreich verschickt", 'success')
            #flash(Question.query.all())
            #flash(question)


@app.route("/", methods=('GET', 'POST'))
@app.route("/home", methods=('GET', 'POST'))
def home():
    post_request()
    return render_template("home.html", buttons=buttons)


@app.route("/piano_lesson", methods=('GET', 'POST'))
def piano_lesson():
    post_request()
    return render_template("piano_lesson.html", title="Klavierunterricht", buttons=buttons)


@app.route("/drums_lesson", methods=('GET', 'POST'))
def drums_lesson():
    post_request()
    return render_template("drums_lesson.html", title="Schlagzeugunterricht", buttons=buttons)


@app.route("/contact", methods=('GET', 'POST'))
def contact():
    post_request()
    return render_template("contact.html", title="Kontakt", buttons=buttons)


@app.route("/register", methods=('GET', 'POST'))
def register():
    if request.method == 'POST':
        name = request.form['name']
        email = request.form['email']
        password = request.form['password']

        name_exists = User.query.filter_by(name=name).first()
        email_exists = User.query.filter_by(email=email).first()

        if not name_exists and not email_exists:
            hashed_password = bcrypt.generate_password_hash(password).decode('utf-8')
            user = User(name=name, email=email, password=hashed_password)
            db.session.add(user)
            db.session.commit()
            flash(f'Erfolgreich als "{name}" registriert', 'success')
            return render_template(url_for('login'))
        elif name_exists:
            flash(f'Der Name "{name}" ist bereits vergeben', 'danger')
        elif email_exists:
            flash(f'Die Email "{email}" ist bereits vergeben', 'danger')
        
    return render_template("register.html", title="Register", buttons=buttons)


@app.route("/login", methods=('GET', 'POST'))
def login():
    if request.method == 'POST':
        email = request.form['email']
        password = request.form['password']

        # check if User exists
        user = User.query.filter_by(email=email).first()
        if user:
            if user.password == password:
                flash("Erfolgreich eingeloggt", 'success')
            else:
                flash("Das Passwort ist falsch", 'danger')
        else:
            flash("Dieser Nutzer existiert nicht", 'danger')

    return render_template("login.html", title="Login", buttons=buttons)


@app.route("/admin", methods=('GET', 'POST'))
def admin():
    return render_template("admin.html", title="Admin", buttons=buttons)


#@app.route("/admin/questions", methods=('GET', 'POST'))
#def admin():
    #return render_template("questions.html", title="Admin", buttons=buttons)
Hier der Fehler mit Traceback:

Code: Alles auswählen

jinja2.exceptions.TemplateNotFound
jinja2.exceptions.TemplateNotFound: /login

Traceback (most recent call last)
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\flask\app.py", line 2088, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\flask\app.py", line 2073, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\flask\app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\flask\app.py", line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\flask\app.py", line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\flask\app.py", line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:\Users\haeus\workspace\theurer_projekt\flask_website\routes.py", line 85, in register
return render_template(url_for('login'))
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\flask\templating.py", line 148, in render_template
ctx.app.jinja_env.get_or_select_template(template_name_or_list),
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\jinja2\environment.py", line 1068, in get_or_select_template
return self.get_template(template_name_or_list, parent, globals)
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\jinja2\environment.py", line 997, in get_template
return self._load_template(name, globals)
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\jinja2\environment.py", line 958, in _load_template
template = self.loader.load(self, name, self.make_globals(globals))
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\jinja2\loaders.py", line 125, in load
source, filename, uptodate = self.get_source(environment, name)
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\flask\templating.py", line 59, in get_source
return self._get_source_fast(environment, template)
File "C:\Users\haeus\workspace\theurer_projekt\venv\Lib\site-packages\flask\templating.py", line 95, in _get_source_fast
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: /login
LukeNukem
User
Beiträge: 232
Registriert: Mittwoch 19. Mai 2021, 03:40

Domroon hat geschrieben: Dienstag 13. Juli 2021, 12:03

Code: Alles auswählen

            return render_template(url_for('login'))
Nunja, "url_for()" ist dazu da, aus einem Funktionsnamen (und eventuellen Parametern) den URL zu generieren, mit dem diese Funktion aufgerufen werden kann. Bei Dir wird also aus dem Funktionsnamen "login" der URL "/login" erzeugt -- und das ist auch vollkommen korrekt. Der Fehler tritt auf, weil die Funktion "render_template()" natürlich kein Template mit dem Namen "/login" finden kann, das korrekte Template heißt, wie in der Funktion "login()" zu lesen, "login.html". Ich vermute daher mal ins Blaue hinein, daß Du anstelle der Funktion "render_template()" lieber die Funktion "redirect()" benutzen möchtest, um den Client auf den URL für die Funktion "login()" umzuleiten.
Benutzeravatar
Domroon
User
Beiträge: 104
Registriert: Dienstag 3. November 2020, 10:27
Wohnort: Dortmund

LukeNukem hat geschrieben: Dienstag 13. Juli 2021, 15:44
Domroon hat geschrieben: Dienstag 13. Juli 2021, 12:03

Code: Alles auswählen

            return render_template(url_for('login'))
Nunja, "url_for()" ist dazu da, aus einem Funktionsnamen (und eventuellen Parametern) den URL zu generieren, mit dem diese Funktion aufgerufen werden kann. Bei Dir wird also aus dem Funktionsnamen "login" der URL "/login" erzeugt -- und das ist auch vollkommen korrekt. Der Fehler tritt auf, weil die Funktion "render_template()" natürlich kein Template mit dem Namen "/login" finden kann, das korrekte Template heißt, wie in der Funktion "login()" zu lesen, "login.html". Ich vermute daher mal ins Blaue hinein, daß Du anstelle der Funktion "render_template()" lieber die Funktion "redirect()" benutzen möchtest, um den Client auf den URL für die Funktion "login()" umzuleiten.
Oh ja :D :D
Ich darf nicht programmieren wenn ich müde bin :D
Vielen Dank Dir ;) Hat mir weiteres suchen erspart :wink:
Antworten