How to Edit Data in Web App Flask and SQL server? - python

I created a web app Flask. I use pyodbc for connect to SQL SERVER database. I display Tbl_product with #app.route('/product'). tbl_product is a table with 4 columns: P_ID, title, count, price. I want to click on Edit of each row in product page and go to Edit page with values of title,count and price same row as default.Then I want to edit this information and return to product page.
my app.py is:
from flask import Flask,render_template,url_for, request, redirect, flash
import pyodbc
app = Flask(__name__)
conn = pyodbc.connect('Driver={SQL Server};'
'Server=TABRIZIYAN;'
'Database=market_DB;'
'Trusted_Connection=yes;')
#app.route('/product')
def product():
cursor = conn.cursor()
resultValue=cursor.execute("SELECT * FROM Tbl_product")
#if resultValue > 0:
productDetails= cursor.fetchall()
cursor.close()
return render_template('product.html', productDetails=productDetails)
#app.route('/edit', methods=['GET','POST'])
def update():
if request.method =='POST':
#fetch form data
productDetails= request.form
P_ID=productDetails['P_ID']
title= productDetails['title']
count=productDetails['count']
price= productDetails['price']
cursor = conn.cursor()
cursor.execute("UPDATE Tbl_product SET title=?, count=?, price=? WHERE P_ID=?",
(title,count,price,P_ID))
conn.commit()
cursor.close()
return redirect('/product')
return (render_template('edit.html'))
my product.html is:
<table bolder= 1px>
<tr>
<td> ID </td>
<td> Title </td>
<td> Count </td>
<td> Price </td>
<td> Action </td>
</tr>
{% for product in productDetails %}
<tr>
<td> {{product[0]}} </td>
<td> {{product[1]}} </td>
<td> {{product[2]}} </td>
<td> {{product[3]}} </td>
<td> <a href='/edit/{{product[0]}}'>Edit</a></td>
</tr>
{% endfor %}
my edit.html is:
<form method="Post" action="">
<h1> Edit product </h1>
ID<br>
<input type="text" name="P_ID"><br>
Title<br>
<input type="text" name="title"><br>
Count<br>
<input type="text" name="count"><br>
Price<br>
<input type="text" name="price"><br>
<br>
<input type="submit">
</form>
How I do it?

My answer is:
app.py changed as below :
#app.route('/product')
def product():
cursor = conn.cursor()
cursor.execute("SELECT * FROM Tbl_product")
productDetails= cursor.fetchall()
return render_template('product.html',
productDetails=productDetails)
#app.route('/edit/<string:P_ID>', methods=
['GET','POST'])
def update(P_ID):
if request.method=='GET':
cursor=conn.cursor()
productDetails1=cursor.execute("SELECT * FROM Tbl_product WHERE P_ID=?",
(P_ID))
productDetails1= cursor.fetchall()
conn.commit()
cursor.close()
return (render_template("edit.html", productDetails1=productDetails1))
if request.method =='POST':
#fetch form data
productDetails= request.form
#P_ID=productDetails['P_ID']
title= productDetails['title']
count=productDetails['count']
price= productDetails['price']
cursor = conn.cursor()
cursor.execute("UPDATE Tbl_product SET title=?, count=?, price=?, active=?
WHERE P_ID=?",(title,count,price,active,P_ID))
conn.commit()
cursor.close()
flash("Data Updated Successfully")
return redirect('/product')
edit.html changed as below :
<form method="Post" action="">
<h1> Edit Product Page </h1>
{% for product in productDetails1 %}
<input type="hidden" name="P_ID" value={{product[0]}}" ><br>
Title:<br>
<input type="text" name="title" value="{{product[1]}}"><br>
Count:<br>
<input type="text" name="count" value="{{product[2]}}"><br>
Price:<br>
<input type="text" name="price" value="{{product[3]}}" ><br><br>
{% endfor %}
<br>
<input type="submit" value="Edit">
</form>

Related

How to autoload html table based on variable in the URL (Python, Flask, Mysql)

Python-
#app.route('/search', methods=['GET','POST'])
def search():
if request.method == "POST":
classname = request.args['class']
cursor.execute("select * from errordata where rule_name like %s", (classname))
conn.commit()
data = cursor.fetchall()
data1 = len(data)
# all in the search box will return all the tuples
if len(data) == 0 and classname == 'all':
cursor.execute("SELECT * from errordata ORDER BY error_date DESC")
conn.commit()
data = cursor.fetchall()
data1 = len(data)
return render_template('search.html', data=data, data1=data1)
return render_template('search.html')
HTML-
<form class="errorboard" method="post" action=""
style="margin:auto;max-width:600px">
<input type="text" placeholder="Search by Rule-Name" name="book">
<div>
Total errors- {{data1}}
</div>
</form>
<table>
<tr bgcolor="#000">
{% for item in data %}
<tr>
<td> {{item[0]}} </td>
<td> {{item[1]}} </td>
<td> {{item[2]}} </td>
<td> {{item[3]}} </td>
<td> {{item[4]}} </td>
<td> {{item[5]}} </td>
<td> {{item[6]}} </td>
<td> {{item[7]}} </td>
<td> {{item[8]}} </td>
</tr>
{% endfor %}
</table>
How to make the HTML table load as soon as I enter the URL, Now I need to click enter or a submit button for the table to load based on the SQL query (Value taken from URL).
Tried to remove the form tag and added the method = POST in table tag, But didnt work. It just goes blank with out a input box for me to submit or enter.

Why not take the data from the inserted in flask?

I am trying to insert several data in one table to another but it is not taking the data from the HTML, I have tried several ways, I also tried to take the number as a variable and insert it directly but it did not work.
This is what I am trying to do, that 2 tables bring me a value and insert them in a table called quantity, which has 2 ids and only 3 fields, where is the id, the count and the id of the product but when I try Insert the data, the page only reloads.
Python
if request.method == 'POST':
try:
dcont = request.form['dcont']
ids = request.form['ids']
cn = request.form['cn']
with sql.connect("DRIVER={SQL Server}; SERVER=AUS_COMPUTO02\SQLEXPRESS; DATABASE=WEBSERVICE; Trusted_Connection = yes;") as con:
cur = con.cursor()
cur = con.execute("INSERT INTO dbo.DETALLECONTEO VALUES (?,?,?)", (dcont,ids,cn))
cur.commit()
msg = "Successfully added"
print(cur)
print(dcont,ids,cn)
except:
con.rollback()
msg = "error inserte la operacion nuevamente"
finally:
# con.close()
return render_template ('result.html')
return render_template('new.html', prov=prov, cnt=cnt, ind=ind )
HTML
<div class="jumbotron">
<div class="form-group">
<form class="form-inline my-2 my-lg-0" action="{{ url_for('new') }}" class="form-control" class="w-auto p-3">
<select name='prove' class="form-control mr-sm-2" aria-label="Search" >
<option value="0"> Selecione su Proveedor </option>
<br action="{{ url_for('new') }}" method='POST'>
{% for p in prov %}
<option value="{{ p.ID }}" > {{ p.DESCRIPCION }} </option>
{% endfor %}
</select>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" >Seclet</button>
</form>
</div>
<div class="form-group">
<form class="form-inline my-lg-0" action="{{ url_for('adt') }}" method='POST'>
<table class="table" class="form-control">
<thead>
<tr>
<th scope="col">Codigo</th>
<th scope="col">Descipcion</th>
<th acope="col">Cantidad</th>
</tr>
</thead>
<tbody>
{% for c in cnt %}
<tr>
<td >{{ c.codigo }}</td>
<td>{{ c.descripcion }}</td>
<td > <input name='cn' id='cn' type="number" class="form-control"></td>
<td><select name='dcont' id='dcont'>
{% for i in ind %}
<option value=" {{i.Conteo}}"> {{i.Conteo}} </option>
{% endfor %}
</select>
</td>
<td> <select name='ids' id='ids'>
<option value="{{c.id}}"> {{c.id}} </option>
</select>
</td>
{% endfor %}
</tr>
</tbody>
</table>
</tbody>
</table>
<input class="btn btn-outline-success my-2 my-sm-0" type="submit" ><br>
</form>
</div>
</div>
Two main areas to focus on-- first your form hasn't been told to 'POST' the data-- go it's going to send it via the default 'GET' mode, changing your form code, by adding method="post" will resolve that issue.
<form class="form-inline my-2 my-lg-0" method="post" action="{{ url_for('new') }}" class="form-control" class="w-auto p-3">
So now your form data will get POST'ed-- and so will trigger the if request.method == 'POST': logic.
Your next issue is your data is coming in as the same named element-- e.g. if you submitted three entries, your ids element would post:
ids=3
ids=2
ids=6
So we need to use the request.form.getlist('ids') to get that data, so you end up with a list of entries for the form elements:
all_ids = request.form.getlist('ids')
all_cn = request.form.getlist('cn')
all_dcont = request.form.getlist('dcont')
Now if we looked at that data that might be submitted:
>>> print(all_ids)
['3','2','6']
>>> print(all_dcont)
['A','B','C']
>>> print(all_cn)
['X','Y','Z']
But we need to handle them as rows-- to insert into our database, so we can zip them together to make 'rows' of the data:
rows = zip(all_ids, all_dcont, all_cn)
So now we have:
>>> print(rows)
['3','A','X'], ['2','B','Y'], ['6','C','Z']
Which we can iterate through (theres a number of ways to do this, we'll keep it simple) to create out SQL statements to execute:
for entry in rows:
query_ids = entry[0]
query_dcont = entry[1]
query_cn = entry[2]
...
cur = con.execute("INSERT INTO dbo.DETALLECONTEO VALUES (?,?,?)", (query_dcont,query_ids,query_cn))
...

How to avoid the below error in Python Flask

I am using the below 3 html i.e. Index.html , Results.html and Edit.html
and python code file app.py code is also pasted below.
The save to the DB is working fine and when I retrieve the data for editing and click on Submit I am encountering the below error
"_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s' at line 1")"
Index.html
<h1>Welcome</h1>
<br>
<br>
<form method="POST" action="{{ url_for('index') }}">
Name <input type="text" name="name" />
<br>
Email <input type="email" name="email" />
<br>
CRType <select name = "CRType">
<option value = "New">New</option>
<option value = "Old">Old</option>
</select><br>
<input type="submit" value="Submit">
</form>
Results.html
Add CR
<table border = 1>
{% for user in userDetails %}
<tr>
<td> {{user[3]}} </td>
<td> {{user[0]}} </td>
<td> {{user[1]}} </td>
<td> {{user[2]}} </td>
<td> Edit Profile </td>
</tr>
{% endfor %}
</table>
Edit.html
h1>Welcome to Update Zone</h1>
<br>
<br>
<body>
<form method="POST" action="{{ url_for('Edit') }}">
CR_ID <input type="text" name="CR_ID" value = "{{user[0]}}"/>
<br>
Name <input type="text" name="name" value = "{{user[1]}}"/>
<br>
Email <input type="email" name="email" value = "{{user[2]}}"/>
<br>
<br>
<input type="submit" value="Submit">
</body>
</form>
App.PY
from flask import Flask, render_template, request, redirect
from flask_mysqldb import MySQL
# from flask_table import Table, Col, LinkCol
app = Flask(__name__)
# Configure db
#db = yaml.load(open('db.yaml'))
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
#app.config['MYSQL_PASSWORD'] = 'P#$$w0rd'
app.config['MYSQL_DB'] = 'flaskapp'
mysql = MySQL(app)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
# Fetch form data
userDetails = request.form
name = userDetails['name']
email = userDetails['email']
CRType = userDetails['CRType']
# CR_ID = userDetails['CR_ID']
cur = mysql.connection.cursor()
# cur.execute("""INSERT INTO users(name, email, CRType) VALUES(%s, %s, % )""",(name, email, CRType)
cur.execute("""INSERT INTO users (name, email, CRType) VALUES (%s, %s, %s)""", (name, email, CRType))
mysql.connection.commit()
cur.close()
return redirect ('/results')
# return redirect('/results')
return render_template('index.html')
#app.route('/results')
def results():
cur = mysql.connection.cursor()
resultValue = cur.execute("SELECT * from users")
if resultValue > 0:
userDetails = cur.fetchall()
# edit = LinkCol('Edit', 'edit', url_kwargs=dict(id='CR_ID'))
return render_template('results.html',userDetails=userDetails)
#app.route('/Edit', methods=['GET', 'POST'])
def Edit():
# request.method == 'GET':
# Fetch form data
# user = request.form
# CR_ID = user['CR_ID']
CR_ID = request.args.get('CR_ID')
name = request.args.get('name')
email = request.args.get('email')
CRType = request.args.get('CRType')
cur = mysql.connection.cursor()
# result= cur.execute("SELECT CR_ID, name, email from users where CR_ID = 1")
result = cur.execute("""SELECT CR_ID, name, email from users where CR_ID = %s""",CR_ID)
# result = cur.execute("Update table users set name=?, email=?, CRType=? where CR_ID = %s", CR_ID)
RV = cur.fetchall()
user = RV[0]
cur.close()
return render_template('Edit.html',user=user)
if __name__ == '__main__':
app.run(debug= True)
Your SQL statements aren't properly formatted. It should be
result = cur.execute("SELECT CR_ID, name, email from users where CR_ID = %s", (CR_ID))

Unable to insert data to the database but it returns success every time i run it

I want to insert data, which i found by iterating using for loop in jinja template, to a table. when i submit the form returns SUCCESS but nothing is registered on the database.
#app.route('/submit', methods=['GET','POST'])
def submit():
if request.method == 'POST':
cur = connection.cursor()
userDetails = request.form
oracle_id = userDetails.getlist('id')
name = userDetails.getlist('name')
status = userDetails.getlist('status')
remark = userDetails.getlist('remark')
for i, id in enumerate(oracle_id):
stmt = "insert into attendance( oracle_id, name, status, shift, remark) VALUES(%s, %s, %s, %s, %s)"
cur.executemany(stmt, (id,oracle_id[i], name[i], status[i], remark[i]))
cur.commit()
return 'That is success'
return render_template('take_attendance.html')
The funny part is once or twice i found the data in my table while testing, but after wards nothing goes there. Is there any error i made here?
The HTML form i used is
<form action="{{ url_for('submit') }}" method="POST" name="attendance">
<table cellpadding="2" width="20%" bgcolor="#F7F7F7" align="center" cellspacing="10">
<tr>
<td colspan=2>
<center><font size=4><p>Attendance</p></font></center>
</td>
</tr>
<tr>
<td align="center">ID</td>
<td align="center">Name</td>
<td align="center">Status</td>
<td align="center">Remark</td>
</tr>
{% for data in userDetails %}
<tr>
<td><input type="text" name="oracle_id" id="oracle_id" size="6" value="{{data.oracle_id}}"></td>
<td><input type="text" name="name" id="name" size="20" value="{{data.name}}"></td>
<td>
<select name="status">
<option value="-1">select..</option>
<option value="A">1130</option>
<option value="W" selected>1122</option>
</select></td>
<td><textarea rows="1" cols="20" name="remark"></textarea></td>
</tr>
{% endfor %}
<tr>
<td>
<input type="reset">
</td>
<td colspan="2">
<input type="submit" value="Submit">
</td>
</tr>
</table>
</form>
I was trying for over a week but nothing changed. Thanks in advance for your effort.
Execute many is used if you prepare a sql statement without data and feed it multiple rows of values - you feed it one tuple, not a list of tuples.
#app.route('/submit', methods=['GET','POST'])
def submit():
if request.method == 'POST':
cur = connection.cursor()
userDetails = request.form
oracle_id = userDetails.getlist('id')
name = userDetails.getlist('name')
status = userDetails.getlist('status')
remark = userDetails.getlist('remark')
# marry the right data:
data = list(zip(range(len(oracle_id)),oracle_id,name,status,remark))
# range(len(oracle_id)) delivers the same ids as your code does
# wich is most probably **wrong** on many levels...
stmt = "insert into attendance( oracle_id, name, status, shift, remark) VALUES(%s, %s, %s, %s, %s)"
cur.executemany(stmt, data) # provide the list of rows to execute many
cur.commit()
return 'That is success'
return render_template('take_attendance.html')
That said, its probably incorrect - you insert as id the index gathered from enumerating(oracle_id) - which will always start at 0 for each new iteration, so you are inserting the same id over different calls to def submit().
Use How to debug small programs to debug your code.

can't add values from field into database Django

I would like to add data filled into database and output it. But i have no idea where is wrong because my data was't saved into database at all. In views.py, Scholarship is just one scholarship object, LScholarship is displaying all the data in Scholarship. I have similar code for other models and views but i have no idea what i did wrong in here, making the data can't be saved into database. Could anyone please advice me where am i wrong
add_remove_scholarship.html
<div align="center" >
<form method="POST" onsubmit="return validation()" action="">
{% csrf_token %}
{{ form.errors }}
<p>Upload File: {{scholarship.doc}} <input id="doc" type="text" name="doc"> </p>
<p>Faculty: {{scholarship.faculty}} <input id="faculty" type="text" name="faculty"> </p>
<p>Opening date: {{scholarship.openDate}} <input id="odate" type="date" name="openDate"> </p>
<p>Closing date: {{scholarship.closeDate}} <input id="edate" type="text" name="closeDate"> </p>
<input type="submit" name="AddScholarship" value="Add Scholarship" >
</form>
</div>
<br></br>
<button id="button" type="button">Delete Selected Scholarship</button>
<br></br>
<form method="POST" action="">
{% csrf_token %}
<table id="example" class="display" cellspacing="0" width="100%" border="1.5px">
<tr align="center">
<th> Scholarship </th>
<th> Faculty </th>
<th> Open Date </th>
<th> Close Date </th>
</tr>
{% for item in query_results %}
<tr align="center">
<td>{{item.doc}}</td>
<td>{{item.faculty}}</td>
<td>{{item.openDate}}</td>
<td>{{item.closeDate}}</td>
</tr>
{% endfor %}
</table>
</form>
models.py
#consists of all the details of the scholarship under the 'Add/Remove
Scholarship'
class Scholarship(models.Model):
doc = models.TextField("Doc", max_length=1000)
faculty = models.TextField("Faculty", max_length=1000)
openDate = models.DateField("Opening Date", max_length=8)
closeDate = models.TextField("CLosing Date", max_length=18)
def __str__(self):
return self.doc
#consists of all the details of the scholarship under the 'Add/Remove
Scholarship'
class LScholarship(models.Model):
scholarship = models.ForeignKey(Scholarship, on_delete=models.CASCADE)
views.py
def scholarship(request):
if request.method == "POST":
form = ScholarshipForm(request.POST)
if form.is_valid():
scholarship = form.save(commit=False)
scholarship.save()
else:
form = ScholarshipForm()
return render(request, 'hrfinance/add_remove_scholarship.html', {'form': form})
def lscholarship(request):
query_results = Scholarship.objects.all()
data={'query_results':query_results}
return render(request, 'hrfinance/add_remove_scholarship.html', data)
class ScholarshipForm(forms.ModelForm):
class Meta:
model = Scholarship
fields = '__all__'
You are using two views to render a single template.
You can merge your views into a single one and maybe reduce the logic.
If I have understood your problem correctly you could use your view more like this,
def scholarship(request, id=None):
query_results = []
if request.method == "POST":
form = ScholarshipForm(request.POST)
if form.is_valid():
scholarship = form.save(commit=False)
scholarship.save()
else:
form = ScholarshipForm()
id = request.GET.get('scholarship')
query_results = Scholarship.objects.all()
data = {
'query_results':query_results,
'form': form,
}
return render(request, 'hrfinance/add_remove_scholarship.html', data)
In your template,
<div align="center" >
<form method="POST" onsubmit="return validation()" action="">
{% csrf_token %}
{{ form.errors }}
<p>Upload File: {{ form.doc }}</p>
<p>Faculty: {{ form.faculty }} </p>
<p>Opening date: {{ form.startDate }} </p>
<p>Closing date: {{ closeDate }} </p>
<button type="submit" name="AddUser" value="Add Scholarship" onclick="add()" >Add Scholarship</button>
</form>
</div>
<table id="example" class="display" cellspacing="0" width="100%" border="1.5px">
<tr align="center">
<th> Scholarship </th>
<th> Faculty </th>
<th> Open Date </th>
<th> Close Date </th>
</tr>
{% for item in query_results %}
<tr align="center">
<td>{{item.doc}}</td>
<td>{{item.faculty}}</td>
<td>{{item.openDate}}</td>
<td>{{item.closeDate}}</td>
</tr>
{% endfor %}
</table>

Categories

Resources