I'm quite new to python and flask. Basically I'm building a very basic web app that allows an admin to add/edit/delete a list of users. The list is display at the main menu and the admin can add/edit/delete first time around. However when I try to add/edit/delete a second time it doesn't work, also it fails if I redirect back to the main menu (where the list of users are) after an add/edit/delete. Any idea's what could be the issue?
from flask import Flask, url_for, request, render_template, redirect;
from app import app;
import pypyodbc;
myConnection = pypyodbc.connect('Driver={SQL Server};'
'Server=local'
'Database=All;'
'uid=sa;pwd=23232')
myCursor = myConnection.cursor()
myCursor.execute('SELECT * FROM Users')
rows = myCursor.fetchall();
for r in rows:
print(r)
#app.route('/')
def home():
"""Renders a sample page."""
createLink = "<a href='" + url_for("display") + "'>Admin</a>";
createLink2 = "<a href='" + url_for("user") + "'>User login</a>";
createLink3 = "<a href='" + url_for("delete") + "'>Delete</a>";
createLink4 = "<a href='" + url_for("edit") + "'>Edit</a>";
return """<html>
<head>
<title>First page</title>
</head>
<body>
<h1>Menu</h1>
<div>
""" + createLink + """
</div>
<div>
""" + createLink2 + """
</div>
<div>
""" + createLink3 + """
</div>
<div>
""" + createLink4 + """
</div>
</body>
</html>"""
#app.route('/display', methods=['GET', 'POST'])
def display():
if request.method == 'GET':
myCursor = myConnection.cursor()
myCursor.execute('SELECT * FROM Users')
rows = [dict(id=row[0], name=row[1], email=row[2], password=row[3]) for row in myCursor.fetchall()]
return render_template('DisplayAll.html', rows = rows)
else:
return"<h2>Error</h2>"
#app.route('/add', methods=['GET', 'POST'])
def add():
if request.method == 'GET':
return render_template('Add.html');
elif request.method == 'POST':
name = request.form['AddName'];
email = request.form['AddEmail'];
password = request.form['AddPassword'];
SQLCommand = ("INSERT INTO Users "
"(Name, Email, Pword) "
"VALUES (?,?,?)")
values = [name, email, password]
myCursor.execute(SQLCommand,values)
myConnection.commit();
#print("works")
#myCursor.execute('SELECT * FROM Users')
#rows = [dict(id=row[0], name=row[1], email=row[2], password=row[3]) for row in myCursor.fetchall()]
myConnection.close();
return ridirect(url_for('display'));
else:
return "<h2>Error</h2>";
#app.route('/delete', methods=['GET', 'POST'])
def delete():
if request.method == 'GET':
return render_template('Delete.html');
elif request.method == 'POST':
try:
DeleteId = request.form['DeleteId'];
SQLCommand = ("DELETE FROM Users "
"WHERE UsererId = "
+ DeleteId)
myCursor.execute(SQLCommand)
myConnection.commit();
#myCursor.execute('SELECT * FROM Users')
#rows = [dict(id=row[0], name=row[1], email=row[2], password=row[3]) for row in myCursor.fetchall()]
myConnection.close();
#return render_template("DisplayAll.html", rows = rows);
return redirect(url_for('display'));
except:
return "<h2>Doesn't work</h2>"
else:
return "<h2>Error</h2>";
#app.route('/edit', methods=['GET', 'POST'])
def edit():
if request.method == 'GET':
return render_template('Edit.html');
elif request.method == 'POST':
try:
Name = request.form['EditName'];
Email = request.form['EditEmail'];
Password = request.form['EditPassword'];
EditId = request.form['EditId'];
SQLCommand = ("UPDATE Users "
"SET Name = '" + Name +
"', Email = '" + Email +
"', Pword = '" + Password +
"' WHERE UsererId = "
+ EditId)
myCursor.execute(SQLCommand)
myConnection.commit();
#print("works")
#myCursor.execute('SELECT * FROM Users')
#rows = [dict(id=row[0], name=row[1], email=row[2], password=row[3]) for row in myCursor.fetchall()]
myConnection.close();
#return render_template("DisplayAll.html", rows = rows);
return redirect(url_for('display'));
except:
return "<h2>Doesn't work</h2>"
else:
return "<h2>Error</h2>";
First off, you have a typo in add() function.
This line:
return ridirect(url_for('display'));
should be
return redirect(url_for('display'));
Next, in display() you define myCursor and then you work with it. That is ok
myCursor = myConnection.cursor()
However, in functions add, delete and edit you are missing this definition, but you are still using it. You can not omit this definition, since the first one is valid only inside display() due to variable scope.
Try adding this definition to other functions as well.
If that does not work, it might be because you also need to make a new connection for every request, not just at the beginning of the file. Then, each function would begin with
myConnection = pypyodbc.connect('Driver={SQL Server};'
'Server=local'
'Database=All;'
'uid=sa;pwd=23232')
myCursor = myConnection.cursor()
Please, let us know if this works for you.
Note: I have just noticed you are actually closing the connection after adding/removing/editing with myConnection.close(). Therefore, you definitely need to reopen the connection upon each request with the code above.
Related
This works but..
views.py
from django.http import HttpResponse
from django.db import connection
def query():
with connection.cursor() as cursor:
cursor.execute('SELECT some, stuff FROM here;')
row = cursor.fetchall()
return row
def index(request):
return HttpResponse(query())
What if I want to get a filtered response that is restricted to a user or group from the admin?
For example, if the user is in the BAIT group they could filter results WHERE email LIKE 'bob#bait.com';
I did it like this...
/opt/my_project/my_app/templates/my_app/generate_html.html
<html>
<h1>Generate HTML</h1>
<form method="POST" action="">
{% csrf_token %}
{{ form }}
<button type="submit">Submit Query</button>
</form>
</html>
/opt/my_project/my_project/settings.py
'DIRS': ['/opt/my_project/my_app/templates/my_app'],
/opt/my_project/my_app/urls.py
path('generate_html/', generate_html, name = "generate_html"),
/opt/my_project/my_app/forms.py
from django import forms
class InputForm(forms.Form):
email = forms.EmailField(max_length = 100)
/opt/my_project/my_app/views.py
def query(email):
with connection.cursor() as cursor:
query = '''SELECT some, stuff
FROM here
WHERE email = %s
ORDER BY stuff;
'''
values = (email,)
cursor.execute(query, values)
select = cursor.fetchall()
return select
def generate_html(request):
if request.method == 'POST':
email = request.POST.get('email', None)
try:
html = '<!DOCTYPE html><html><body>'
for row in query(email):
some, stuff = row
html += 'Row: ' + some + ' ' + stuff + '<br>'
html += '<br><br>' + 'Search Again!' + '</body></html>'
return HttpResponse(html)
except Exception as e:
return HttpResponse(str(e))
else:
context ={}
context['form']= InputForm()
return render(request, "generate_html.html", context)
I am currently struggling to get my program working. What I am doing is connecting my database, which is a MySQL database on the workbench, and connecting it to my python. I am trying to store the user inputs as parameters in the stored procedure in my workbench. So when I hit submit the program will take the user input as parameters using the stored procedure. But I am running into several errors. The recurring one being this specific type of error.
Error Message : TypeError: The view function for 'signIn' did not return a valid response. The function either returned None or ended without a return statement.
Python Imports/Code:
from flask import Flask, app, render_template, url_for, request, redirect
import MySQL.connector, CGI
form = cgi.FieldStorage()
app = Flask(__name__)
#app.route('/')
def home():
return "<a href='/login'> login </a><br> <a href='/sign-up'> sign-up </a>"
#app.route('/sign-up', methods=["POST", "GET"])
def signIn():
condition = 0
mydb = mysql.connector.connect(host='localhost', database='signlogpy', user='root', password='thereaper1999',
port="3306")
cursor = mydb.cursor()
if request.method == "POST":
email = request.form["email"]
password = request.form["password"]
name = request.form["name"]
displayName = request.form["displayName"]
DOB = request.form["dateOfBirth"]
args = [email, password, name, displayName, DOB]
else:
return print("Could not reveice user input")
if condition == 0:
condition = 1
elif condition == 1:
results = cursor.callproc('signInInformation', args)
cursor.execute('select * from signin')
cursor.fetchall()
else:
return render_template("SignUp.html")
signInInformationProc = cursor.callproc('signInInformation', args)
results = cursor.fetchall()
print(results)
if results == True:
print("works")
redirect(url_for('login'))
else:
render_template("SignUp.html")
return redirect(url_for(login))
#app.route('/login')
def login():
return render_template('Login.html')
if __name__ == '__main__':
app.run(debug=True)
Workbench MySql code:
use signlogpy;
DELIMITER $$
create procedure signInInformation
(
in
p_userEmail varchar(45),
p_userPassword varchar(45),
p_name varchar(45),
p_displayName varchar(45),
p_dob date
)
begin
insert into signin (userEmail, userPassword, name, displayName, dob)
values (p_userEmail, p_userPassword, p_name, p_displayName, p_dob);
end $$
DELIMITER ;
Any help would be greatly appreciated. If anybody does reply I do thank you immensely and appreciate your help. Thanks in advance!
It looks like the declaration of args is inside
if request.method == "POST":
which means that args doesn't have any meaning outside and after that if statement. Try putting
args = []
at the beginning of signIn() which will let it be accessible by the whole function.
kindly help it out folks! I am new to programming. I am trying to Authenticate Login. But its showing "TypeError....." i couldn't figure out.
See Below This is My code (main.py)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
email = request.form.get('EMAIL')
con1 = sqlite3.connect("check10.db")
cur = con1.cursor()
data = cur.execute("SELECT EMAIL FROM register WHERE EMAIL = ? ", (email,))
if data == email:
return render_template('homepage.html')
else:
alert = "Check Credentials "
return render_template('loginpage.html', alert)
return render_template("loginpage.html")
Try this:
from flask import request, render_template, flash
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
email = request.values.get('EMAIL')
con1 = sqlite3.connect("check10.db")
cur = con1.cursor()
data = cur.execute("SELECT EMAIL FROM register WHERE EMAIL = ? ", (email,))
if data == email:
return render_template('homepage.html')
else:
flash('Check Credentials ')
return render_template('loginpage.html')
return render_template("loginpage.html")
Try also to change the variable email like:
email = request.args.get('EMAIL')
You are getting error because of return render_template('loginpage.html', alert).
If you want to send some data from server to HTML page then you can refer to link.
If you want flash message 'check credentials' to the user then refer to this Link
I'm setting a new server in Flask for an API. And a server to render the frontend in Flask also. Ok, so when i make a request to a determine API route i get this strange response 'This page was not found'. I it really seems to be every thing ok how can i debug this bug? Other Strange thing is that it allways give me status 200 OK. The error is in the route: #app.route('/v1.0/aluno/update/', methods=['POST'])
API SIDE
#app.route('/v1.0/aluno/<int:aluno_id>', methods=['GET'])
def aluno(aluno_id):
if request.method == 'GET':
cur = mysql.connection.cursor()
query = "SELECT NOME, NUMERO, PASSWORD FROM aluno WHERE NUMERO=%s"
cur.execute(query, (aluno_id,))
data = cur.fetchall()
if len(data) <= 0:
return Response(status=404)
else:
aluno = {
'nome': data[0][0],
'numero': data[0][1],
'password': data[0][2]
}
js = json.dumps(aluno)
resp = Response(js, status=200, mimetype='application/json')
resp.headers['Links'] = 'http://127.0.0.1/aluno'
return resp
#app.route('/v1.0/aluno/delete/<int:aluno_id>', methods=['POST'])
def aluno_delete(aluno_id):
if request.method == 'POST' and request.form['_method'] == 'delete':
query = "DELETE FROM aluno WHERE NUMERO = %s"
cur = mysql.connection.cursor()
cur.execute(query, (aluno_id,))
mysql.connection.commit()
cur.fetchall()
cur.close()
return Response(status=200)
#app.route('/v1.0/aluno/update/<int:aluno_id>', methods=['POST'])
def aluno_update(aluno_id):
form = AlunoForm(request.form)
if request.method == 'POST' and form.validate():
nome = request.form["nome"]
numero = request.form["numero"]
password = request.form["password"]
cur = mysql.connection.cursor()
query = "UPDATE aluno SET NOME=%s, NUMERO=%s, PASSWORD=%s WHERE NUMERO = %s"
cur.execute(query, (nome, numero, password, aluno_id))
mysql.connection.commit()
cur.execute(
"SELECT NOME, NUMERO FROM aluno WHERE NUMERO = %s", (aluno_id,))
data = cur.fetchall()
cur.close()
print(" * DATA ")
print(data)
aluno = {
'nome': data[0][0],
'numero': data[0][1]
}
js = json.dumps(aluno)
resp = Response(js, status=200, mimetype='application/json')
resp.headers['Links'] = 'http://127.0.0.1/aluno'
return resp
elif request.method == 'POST' and not form.validate():
resp = Response(status=400)
resp.headers['Links'] = 'http://127.0.0.1/aluno'
return resp
FRONT-END SIDE
{% endblock %}
<script type="text/javascript" src="{{url_for('static', filename='js/jquery-3.2.1.min.js') }}"></script>
<script type="text/javascript" src="{{url_for('static', filename = 'js/bootstrap.min.js')}}"></script>
<script>
function aluno_update(){
try{
let formElement = document.getElementById("aluno_update")
//let formData = formElement.
//console.log(formData)
$.ajax({
type: "POST",
url: "http://127.0.0.1:80/v1.0/aluno/update/{{aluno['numero']}}",
data: {'nome': 'João Luis','numero':'16172','password':'Password'},
//dataType: 'json',
success: function(data){
//location.href = "http://127.0.0.1:3000/v1.0/alunos/"
alert(data)
console.log(data)
},
error(jqXHR,JQueryXHR,errorThrown){
//console.log(formData)
alert(jqXHR)
alert(JQueryXHR)
alert(errorThrown)
console.log(jqXHR)
console.log(JQueryXHR)
console.log(errorThrown)
}
})
}catch(err){
alert(err)
}
}
</script>
I have tried using POSTMAN instead of the regular web browser. To make the request to the API. But i get the same response: 'This page was not found'
At least i was expecting some sort of 400 Bad Request or something like that.
https://github.com/joaogracio/SqlParser
Form validation fails and you get 400 according to the code below
elif request.method == 'POST' and not form.validate():
resp = Response(status=400)
resp.headers['Links'] = 'http://127.0.0.1/aluno'
return resp
im trying to do a blog post simple app in witch you can write and than edit or delete a post.
I got so far that i can show post but i can not edit them
i did a /edit.html page on witch i would like to have a single blog post and than edit it. The problem is that the post does not appear
app.py
from flask import Flask, render_template, request
from flask_mysqldb import MySQL
import yaml
from flask_bootstrap import Bootstrap
app=Flask(__name__)
bootstrap = Bootstrap(app)
db = yaml.load(open('db.yaml'))
app.config['MYSQL_HOST'] = db['mysql_host']
app.config['MYSQL_USER'] = db['mysql_user']
app.config['MYSQL_PASSWORD'] = db['mysql_password']
app.config['MYSQL_DB'] = db['mysql_db']
mysql = MySQL(app)
#app.route('/', methods=['GET','POST'])
def index():
if request.method == 'POST':
form = request.form
user_name = form['user_name']
besedilo = form['besedilo']
cur = mysql.connection.cursor()
cur.execute("INSERT INTO post(user_name, besedilo) VALUES(%s, %s)", (user_name, besedilo))
mysql.connection.commit()
return render_template('index.html')
#app.route('/post/')
def post():
cur = mysql.connection.cursor()
result_value = cur.execute("SELECT * FROM post")
if result_value > 0:
posts = cur.fetchall()
return render_template('post.html',posts = posts)
#app.route('/edit/<int:id>/', methods=['GET','POST'])
def edit(id):
cur = mysql.connection.cursor()
result_value = cur.execute("SELECT * FROM post WHERE post_id = {}".format(id))
if result_value > 0:
post = cur.fetchone()
return render_template('edit.html', post = post)
## here i would like to single out one entry and show it on
#app.route('/delete/')
def delete():
return render_template('delete.html')
if __name__ == '__main__':
app.run(debug=True)
edit.html
{% extends 'base.html' %}
{% block sub_content %}
<h1>{{post['user_name']}}</h1>
<h1>{{post['besedilo']}}</h1>
{% if posts %}
{% for post in posts %}
<h3> {{edit['title']}}</h3>
{%endfor%}
{% endblock %}
this should show single entry
You may need to pass a properly prepared sql query not dynamic.
Try modifying your view like:
#app.route('/edit/<int:id>/', methods=['GET','POST'])
def edit(id):
cur = mysql.connection.cursor()
query = "SELECT * FROM post WHERE post_id = {}".format(id)
result_value = cur.execute(query)
if result_value > 0:
post = cur.fetchone()
return render_template('edit.html', post = post)
Alternatively;
result_value = cur.execute("SELECT * FROM post WHERE post_id = %s", (id,))