Flask: Why am I getting a 404 error? - python

I'm brushing up on my Flask skills to make a "Jeopardy score keeper" application. What I'm trying to do right now is to take a player's score from a database and display it on the screen. I keep getting a "404 NOT FOUND" error. Here's my code:
JeopardyApp.py
#app.route('/layout', methods=['POST'])
def layout():
db = get_db()
try:
cur1 = db.execute('SELECT score FROM {tn} where name="Tyler"'.format(tn="Score"))
score1 = cur1.fetchone()
except:
flash("This person doesn't exist in our database!")
return render_template('layout.html', score=score1)
layout.html
<!doctype html>
<title>JeopardyApp</title>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<div class=page>
<h1>Jeopardy Score Keeper</h1>
<div class=metanav>
<p>Currently under construction...</p>
</div>
<div>
<p>Tyler</p>
<tr><td>{{ score.score }}</td></tr>
</div>
{% for message in get_flashed_messages() %}
<div class=flash>{{ message }}</div>
{% endfor %}
{% block body %}{% endblock %}
</div>
Any help is appreciated. Thank you.

The route you've set for the layout function is only reachable via the POST method.
By default, your webbrowser uses the GET method.
Change your route this way:
#app.route('/layout', methods=['GET'])

Related

Show variable from flask in include html page

I have header.html:
<body>
<a class="navbar-brand mr-4 d-flex align-items-center" href="{{ url_for('dash') }}">
<img class="img-fluid" src="../static/assets/images/live-steam/logo.png" alt="Image">
<p class="px-1 font-weight-bold font-14">{{sys_domain}}</p>
</a>
</body>
and .py code:
#flask.route('/header')
def header():
cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cur.execute('SELECT * FROM system_settings')
user = cur.fetchone()
sys_domain = (user['system_name'])
return render_template("header.html", sys_domain=sys_domain)
When i include this header page to another page '{{sys_domain}}' show nothing!
example of page that header.html include to it:
<body>
<header>
{% include 'header.html' %}
</header>
</body>
I believe it is because when you try to use include, it will not call via the flask route. It is including the template directly and rendering it. You can check this official template documentation link
You can use the "with" keyword of jinja2 to call it that way.
You can check this link to have an idea of this.
You can retrieve the user['system_name'] from mysql as sys_domain variable in the route function of .py code from where you are calling the html file in which header.html is to be called. Then you can do something like this.
{% with sys_domain=sys_domain %}
{% include 'header.html' %}
{% endwith %}

Use of with for getting flashed messages in flask [duplicate]

This question already has answers here:
How does the 'with' statement work in Flask (Jinja2)?
(2 answers)
Closed 4 years ago.
I was checking the message flashing in flask framework from here.
This is a basic example where a template file (Index.html) is used to provide the initial link and another template file (Login.html) creates the form.
The files are:
Login.html:
<!doctype html>
<html>
<body>
<h1>Login</h1>
{% if error %}
<p><strong>Error:</strong> {{ error }}
{% endif %}
<form action = "" method = post>
<dl>
<dt>Username:</dt>
<dd>
<input type = text name = username
value = "{{request.form.username }}">
</dd>
<dt>Password:</dt>
<dd><input type = password name = password></dd>
</dl>
<p><input type = submit value = Login></p>
</form>
</body>
</html>
Index.html:
<!doctype html>
<html>
<head>
<title>Flask Message flashing</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li<{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<h1>Flask Message Flashing Example</h1>
<p>Do you want to <a href = "{{ url_for('login') }}">
<b>log in?</b></a></p>
</body>
</html>
Flash.py:
from flask import Flask, flash, redirect, render_template, request, url_for
app = Flask(__name__)
app.secret_key = 'random string'
#app.route('/')
def index():
return render_template('index.html')
#app.route('/login', methods = ['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or \
request.form['password'] != 'admin':
error = 'Invalid username or password. Please try again!'
else:
flash('You were successfully logged in')
return redirect(url_for('index'))
return render_template('login.html', error = error)
if __name__ == "__main__":
app.run(debug = True)
The part that is confusing me is inside index.html. It's using with messages = get_flashed_messages() to get the messages from the session. I do not fully understand why it's using with? I know with is used for resources, files, streams etc to control the closing procedure (and for not leaving something open when something goes wrong etc). What's the resource it's accessing using with in this context?
I tried removing it (in this context) and an error occurred:
jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag
'messages'.
Also, example use cases from programcreek.com does not use with with get_flashed_messages so what's the case here?
Jinja templates are not Python. with in a template is not a Python context manager, it just introduces a new scope; this code definesa new variable messages that is only visible until the endwith.
See the docs.
try to fix index.html
<!doctype html>
<html>
<head>
<title>Flask Message flashing</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<h1>Flask Message Flashing Example</h1>
<p>Do you want to <a href="{{ url_for('login') }}">
<b>log in?</b></a></p>
</body>
</html>

Flask custom form in home Tab with custom action

I'd like to visualize a form in home/admin page that allows users to select a value from a list (values belongs to a db table) and a button to execute a custom python method.
I am not able to understand if it's possibile to show a form without showing data of if it's possible to run code without flask-admin.
P.s. the same (simple) code that I use to create a form (just 2 datepickers) in Flask works but as soon as I put it in /home/admin the html and flask-admin cannot talk (exchange the values in the form) anymore.
Update:
This is part of my Flask-admin code:
class ExampleForm(Form):
dt_start = DateField('DatePicker', format='%Y-%m-%d')
dt_end = DateField('DatePicker', format='%Y-%m-%d')
#app.route('/admin', methods=['POST','GET'])
def index():
form = ExampleForm()
if form.validate_on_submit():
print("Start date: ", form.dt_start.data.strftime('%Y-%m-%d'))
print("End date: ", form.dt_end.data.strftime('%Y-%m-%d'))
return "Form is OK!"
return render_template('admin/index.html', form=form)
HTML CODE:
{% extends "admin/master.html" %}
{% block body %}
<head>
<title>Download form</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<div class="container">
<h1>Please insert the dates</h1>
<br>
<form action="#" method="post">
{{ form.dt_start(class='datepicker') }}
{{ form.hidden_tag() }}
{{ form.dt_end(class='datepicker') }}
{{ form.hidden_tag() }}
<input type="submit"/>
</form>
</div>
{% endblock %}
ERROR:
jinja2.exceptions.UndefinedError: 'form' is undefined
Thanks a lot
Alessandro

Python: TypeError: redirect() got an unexpected keyword argument 'error'

I'm using Flask and I'm trying to make an error show up when one of the form parts haven't been filled in. When I test this (filling in all the form parts), it gives me the error: "TypeError: redirect() got an unexpected keyword argument 'error'". What am I doing wrong?
Flask code:
#app.route('/crudcourse', methods = ['POST'])
def crudcourse():
db = get_db()
error = None
button = request.form['submitcourse']
coursename = request.form['coursename']
description = request.form['description']
if coursename != None or description != None:
error = 'Vul alle velden in aub'
else:
if button == 'Toevoegen':
db.execute('insert into courses (coursename, description)
values(?, ?)', coursename, description)
db.commit()
flash('Gegevens sucessvol toegevoegd')
elif button == 'Updaten':
db.execute('update courses set coursename=?, description=? where
coursename=? or description=?',
coursename, description, coursename, description)
db.commit()
flash('Gegevens sucessvol geupdate')
elif button == 'Verwijderen':
db.execute('delete from courses where coursename=? or
description=?', coursename, description)
db.commit()
flash('Gegevens sucessvol verwijderd')
return redirect('/intranet/richtingen.html', error=error)
HTML code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Home</title>
<link rel="stylesheet" type="text/css" href="templates/style.css">
</head>
<body>
{% if error %}
<p class=error><strong>Error:</strong> {{ error }}
{% endif %}
{% for message in get_flashed_messages() %}
<div class=flash>{{ message }}</div>
{% endfor %}
<div id="courses">
<form action="/crudcourse" method="post">
<p>Naam<input type="text" name="coursename"></p>
<p>Beschrijving
<textarea name="description" cols="50" rows="4">
</textarea></p>
<input type="submit" name="submitcourse" value="Toevoegen">
</input>
<input type="submit" name="submitcourse" value="Updaten">
</input>
<input type="submit" name="submitcourse" value="Verwijderen">
</input>
</form>
</div>
</body>
</html>
I'm guessing that the redirect method you're referring to is the one that is provided from the flask library, flask.redirect. That can be imported like this:
from flask import redirect
If this is true, this redirect method doesn't take an error argument, as the error message is saying TypeError: redirect() got an unexpected keyword argument 'error'.
It seems like what you want to do is to pass any potential errors to the /intranet/richtingen.html page, if so - I would recommend doing so in a query string to the URL instead, like this:
return redirect('/intranet/richtingen.html?error=%s' % error)

django-mptt children selection works on localhost but not on server

I have the same code on localhost and on server (thanks to mercurial), but it works a little bit different. I want to render category and its subcategories in template using this code:
views.py:
def category(request, category_slug):
try:
category = Category.objects.get(slug=category_slug)
except:
raise Http404
subcats = category.get_children()
return render_to_response('catalogue.html',
{'category': category,
'subcats': subcats,
'header_template':'common/includes/header_%s.html' % flixwood_settings.CURRENT_SITE
},
context_instance=RequestContext(request))
template:
<div class='subcats'>
{% for subcat in subcats %}
{% ifequal subcat.level 1 %}
<div class="item">
<img src="{% thumbnail subcat.image 66x66 %}" class="thumb">
{{ subcat.category }}
{{ subcat.short_description|safe }}
<div class="clear_left"></div>
</div>
{% cycle '' '' '<div class="clear_left"></div>'|safe %}
{% endifequal %}
{% endfor %}
</div>
but however this code works perfectly on localhost (subcategories are rendering right) - it doesn't work on server, and the {{ subcats|length }} returns 0.
I compared values from MySQL bases on localhost and on server - they are right and inheritance should work. The funniest thing is that the same query works perfectly in manage.py shell on server.
What the hack is wrong with it?
The problem was solved - it was in .pyc files, which are recreating only after apache is restarted. That's why the right code in .py files didn't work.

Categories