Query input data from HTML to flask mysql - mysql

I am both new to flask and posting here.
I am trying to query a MySQL database with a variable input from HTML to Flask.
If I fix the query from the python code, it works. However, trying to query my database using the input variable doesn't give any result.
Here is my HTML code for the input variable :
<div class="search">
<form action="{{ url_for('search') }}" method="POST">
<input type=text name="search"></br>
<div class="actions"><input type=submit value="Search"></div>
</form>
</div>
Here is the python code for the search query:
#app.route('/search', methods=["POST" , "GET"])
def search() :
if request.method == "POST" :
search = request.form["search"]
cursor=mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute( '''SELECT * FROM sites WHERE SITE_CODE=(%s)''', (search,))
data=cursor.fetchall()
return render_template("search.html", data=data , search=search )
else :
return render_template("search.html")
here is the jinja2 code for the output :
<table>
<td>Site Code</td>
<td>OM VLAN id</td>
<td>IuB VLAN id</td>
<td>Abis VLAN id</td>
<td>S1X2 VLAN id</td>
</tr>
{% for sites in data %}
<tr>
<td>{{sites.SITE_CODE}}</td>
<td>{{sites.OM_VLAN_id}}</td>
<td>{{sites.IuB_VLAN_id}}</td>
<td>{{sites.Abis_VLAN_id}}</td>
<td>{{sites.S1X2_VLAN_id}}</td>
</tr>
{% endfor %}
</table>
I have a fully ready to use database(I do not have to change anything in it, I just need to query searched data from it) note that everything is working fine when I try to show all the data from the table :
#app.route("/")
#app.route('/IP_PLAN',methods=['GET','POST'])
def IP_PLAN():
cursor=mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute("SELECT * FROM sites")
data=cursor.fetchall()
return render_template("IP_PLAN.html",data=data)
UPDATE:
everything actually works, I just need to type the exact name of the "SITE_CODE". is there any way to get a result without doing it? I want to get as an output all the sites that contain an A in their SITE_CODE for example.
Thanks
UPDATE 2:
I finally achieved what I wanted to do, I just had to change the cursor.execute command :
cursor.execute( 'SELECT * FROM sites WHERE SITE_CODE LIKE %s', ['%' + search + '%'])

Related

Flask-SQLAlchemy MySQL application won't write to database [duplicate]

I'm using Flask-WTF:
Here is my form:
from flask.ext.wtf import Form, TextField
class BookNewForm(Form):
name = TextField('Name')
Here is the controller:
#book.route('/book/new', methods=['GET', 'POST'])
def customers_new():
form = BookNewForm()
if form.is_submitted():
print "submitted"
if form.validate():
print "valid"
if form.validate_on_submit():
flash("Successfully created a new book")
return redirect(url_for('.books_show'))
return render_template('views/books_new.html', form=form)
Now the problem is, if you look at my print statements, it always prints submitted, but it NEVER prints valid and validate_on_submit() is never executed. Why?
You're not inserting the CSRF field in the HTML form.
<form method=post>
{{ form.csrf_token }}
{{ form.name }}
<input type=submit>
</form>
After adding form.csrf_token to the template (docs), the form will validate as expected.
Add print(form.errors) after validating the form to see the errors that were raised. errors will be empty before validation. In this case, there is an error about missing
#book.route('/book/new_no_csrf', methods=['GET', 'POST'])
def customers_new_no_csrf():
form = BookNewForm()
print(form.errors)
if form.is_submitted():
print("submitted")
if form.validate():
print("valid")
print(form.errors)
if form.validate_on_submit():
flash("Successfully created a new book")
return redirect(url_for('.books_show'))
return render_template('books_new.html', form=form)
{}
submitted
{'csrf_token': [u'CSRF token missing']}
127.0.0.1 - - [29/May/2012 02:01:08] "POST /book/new_no_csrf HTTP/1.1" 200 -
127.0.0.1 - - [29/May/2012 02:01:08] "GET /favicon.ico HTTP/1.1" 404 -
I created an example on GitHub.
you can print errors
print form.errors
or
app.logger.debug(form.errors)
and if you got csrf-error, you should set form.csrf_token in your template.
I came across this when trying to render a FormField being iterated over my FieldList in my template. I had to embed two hidden_tag elements one for the FieldList form and one for the FieldForm form, search the template comments for keyword "HIDDEN TAG"
class ParamRangeForm( FlaskForm ):
minX = FloatField( )
maxX = FloatField( )
class ParamRangesForm( FlaskForm ):
paramRanges = FieldList( FormField( ParamRangeForm ) )
submit = SubmitField( 'Submit' )
def loadParams( self ) :
for paramName in ["p1" , "p2" , "p3", "p4"] :
prf = ParamRangeForm( )
prf.minX = -100.9#float('-inf')
prf.maxX = 100.5#float('-inf')
self.paramRanges.append_entry( prf )
...
<form action="" method="POST" enctype="multipart/form-data">
{{ rangesForm.hidden_tag() }} <!--#### HIDDEN TAG #1 -->
<table>
<!--Print Column Headers-->
<thead>
<tr>
<th class="ColumnHeader">Parameter</td>
<th class="ColumnHeader">Min</td>
<th class="ColumnHeader">Max</td>
</tr>
</thead>
<!--Print Parameter Rows-->
<tbody>
{% for paramRange in rangesForm.paramRanges %}
<tr>
{{ paramRange.hidden_tag() }} <!--#### HIDDEN TAG #2 -->
<td>p{{ loop.index }}</td>
<td>{{ paramRange.minX }}</td>
<td>{{ paramRange.maxX }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{{ rangesForm.submit() }}
</form>
insert this after the tag in template html file:
{{ form.csrf_token }}
I was clearing the flask session if I wasn't logged in before every request. This was causing this issue.
#main.before_request
def before_request():
if not current_user.is_authenticated():
# TODO clean sessions may cause CSRF missing issue
session.clear()
print "Session Cleared"
return redirect(url_for('auth.login'))
I think the API has changed.Maybe try changing
from flask.ext.wtf import Form
to:
from flask_wtf import Form
I spent a several hours debugging a validation issue with Flask-WTF. The issue like many others was a CSRF validation issue. However, mine was not caused by any of the common issues I have found.
The standard Flask-WTF implementation of CSRF requires two things be delivered to the browser.
One: The hidden CSRF form field e.g.
<input id="csrf_token" name="csrf_token" type="hidden" value="ImYzODdmZTdhYTRlMmNkYWRjYmRlYWFmZjQxMDllZTQ1OWZmYzg3MTki.XKvOPg.gUCkF9j-vg0PrL2PRH-v43GeHu0">
Two: The session cookie HTTP response header e.g.
Set-Cookie: session=eyJjc3JmX3Rva2VuIjoiZjM4N2ZlN2FhNGUyY2RhZGNiZGVhYWZmNDEwOWVlNDU5ZmZjODcxOSJ9.XKvOPg.a3-W62MHvaGVkv2GYCi-dgpLE3Y; HttpOnly; Path=/
If either of these are missing the browser will fail to send the proper CSRF validation. Of course, this in turn causes the form validation to fail.
If the csrf_token hidden field is present in the form but the session cookie is missing, you will receive the following response when the form is submitted...
Bad Request
The CSRF session token is missing.
In my case the session cookie was missing because of a bug in my code. I needed to serve a custom HTTP header across the entire Flask site. I included it like this...
class LocalFlask(Flask):
def process_response(self, response):
response.headers['my-header'] = 'My Header Value'
return response
app = LocalFlask(__name__)
This however causes anything that rellys on the the Flask.response.headers method to fail. One of those is Flaks-WTF setting the session cookie HTTP header.
This can be solved by adding the super() method to the LocalFlask class so that it inherits methods form the Flask class.
class LocalFlask(Flask):
def process_response(self, response):
response.headers['my-header'] = 'My Header Value'
#LocalFlask inherits methods from Flask
super(LocalFlask, self).process_response(response)
return response
app = LocalFlask(__name__)
Well I tried all the solutions mentioned
form.hidden_tag()
form.csrf_token
form.csrf
with
app.secret_key=""
app.config["SECRET_KEY"]=""
but form.validate_on_submit() always returned false.
None of these seem to work for me, so I used the basic method and this method
import request
request.method="POST"
or
form.is_submitted()
These two worked for me

how to split a string based on delimiter in go html template

I am using go html templates for alerting through bosun using prometheus queries .
Below is the use case in my promql result I get instance name as instancename:9100 (example - xyz.com:9100) while setting up alerts I just need xyz.com , below is the snippet that I used using split function but that is not working . can someone please help here
result from promql would be like below
{dc="IN",env="production",instance="xyz.com:9100",job="node-exporter",service="test"}
code snippet used using go html templates
<table style="border-spacing:0; border-collapse:collapse;">
<tr>
<td><b>Host</b></td>
<td><b>Used Memory (%)</b></td>
{{ range $v := .LeftJoin .Alert.Vars.result .Alert.Vars.result}}
{{ $res := index $v 0 }}
<td>{{(split ":" $res.Group.instance)._0 }}</td>
<td>{{$res.Group.value}}</td>
{{
<td>

How to pass input value to function in view.py

Objective:
** To pass input value itemnumbervalue to itemnumber() in views.py
> Error occured:
method object is not subscribable line 17 in view.py
Already applied techniques to correct the problem:
case 1: Tried [] and () both braces
if (request.POST.get['submitted']):
c = request.POST['ENTER_ITEM_NUMBER']
I tried many options like "remove get", and tried braces() and []
views.py:
from .forms import InputForm
def home_view(request):
context1 ={}
context1['form'] = InputForm(request.POST)
return render(request, "input.html", context1)
def itemnumber(request):
if (request.POST.get['submitted']):
c = request.POST['ENTER_ITEM_NUMBER']
print("input valuegiven by user",c)*
cursor = connection.cursor()
try:
itemnumbervalue = c
C=cursor.execute(f"EXEC ValidateBusinessrule '0000000000{itemnumbervalue}'")
result_set = cursor.fetchall()
result_set1= [' {} '.format(x) for x in result_set]
context = {"row": result_set1}
return render(request, "home.html", context)
finally:
cursor.close()
forms.py
class InputForm(forms.Form):
regex = re.compile('^([1-9]{8})$', re.UNICODE)
ENTER_ITEM_NUMBER= forms.RegexField(max_length=8, regex=regex,help_text=("Required 8 digits between {0-9}."))
home.html
<body>
<table>
<tr>
<ul>
<th>(column 1,column 2)</th>
</ul>
<tr>
<ul >
{% for row in row %}
<td style= "text-align: center;">
{{ row }}
</td>
</ul>
</tr>
{% endfor %}
</tr>
</table>
</body>
input.html
<body>
<form action = "{% url 'item'%}" method = "POST">
{% csrf_token %}
{{form}}
<input type="submit" value=Submit" name="submitted">
</form>
</body>
problem details:
To get input from user and give this input to itemnumbervalue in itemnumber() in view.py. I already validated by putting itemnumbervalue='12345678' (without input value from user) is working fine and getting resultant table.
Try using request.POST.get('submitted') or request.POST['submitted'].
The difference is just that .get method returns None if key is not found in the dictionary, But with directly indexing key if the key is not found then it will throw KeyError exception.
To see what values you are getting in request.POST you can print it.
Also in print("input valuegiven by user",c)* remove the * at the end that's an invalid syntax.
P.S. I tried reproducing this issue and was successful in resolving by above specified method.

How to determine which button is pressed

I have a table in which I populate with data from the database. Some of this I have an extra feature of the delete button. But I can't understand how I get that what delete button is pressed in django
<tbody>
{% for i in list %}
<tr>
<td>{{i.id}}</td>
<td>{{i.reason}}</td>
<td>{{i.starting_date}}</td>
<td>{{i.ending_date}}</td>
<td>{{i.accept_or_not}}</td>
{% if i.accept_or_not == 'pending'%}
<td><input type="button" name="data_delete_{{i.id}}" value="delete"></td>
{%endif%}
</tr>
{% endfor%}
</tbody>
def profile_view(request):
if 'data_delete_id' in request.POST:
# i don't know how to determine the id in the button
This might be straight-forward. You can get the name of the button first and then parse the id such as:
def profile_view(request):
delete_button_id = ""
for name in request.POST.values():
if name.startswith('data_delete_'):
delete_button_id = int(name.split('_')[2])
break
# you now have the id in your delete_button_id variable
According to Django Docs for HttpRequest.POST your python code has to work as expected because POST returns a dict like Object.
def profile_view(request):
if 'data_delete_id' in request.POST:
But in your template you are using <input type="button" .
This will only trigger a client side operation. If you are not having any JS code which you have not shown here, I would say you need to use <input type="submit" instead.
I would also recommend to use <button type="submit" instead of input because from a semantic perspective it is more accurate.

html forms download file django

I am stuck with this issue in Django: I want to download a file already existing on my server through a html form. The file to be downloaded is served through a function in views. My problem is with html form and passing the file name to view. How can I pass the name of the file from form toward view without having to select the file?
In html I have:
# 'content' keeps the name of the file to be downloaded
{% block content %}
{{content}}
<table>
<tr>
<td>
<form action="" method="POST" enctype="multipart/form-data">
<input type="file" name="file"/>
<br />
<input type="submit" value="Download File" />
</form>
</td>
</tr>
</table>
{% endblock %}
When I select the file and press submit button, it works but I need a different behavior: the name of the file containing results (downloadable file) to be passed to views into a variable. The views will then serve it.
The view which handled the downloadable file:
def forecast(request):
if request.method == 'POST':
#handle_download_file(request.FILES['file'], str(request.FILES['file']))
print('request.method este: ',request.method)
RESULTS_filename = 'frcst_'+ str(request.FILES['file'])
#download('GET', RESULTS_filename)
file_path = os.path.join(os.path.relpath('forecast/'), RESULTS_filename)
print (file_path)
print(settings.MEDIA_ROOT)
with open(file_path,'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
response['content-disposition'] = 'attachment; filename='+RESULTS_filename
print(response)
return response
HttpResponseRedirect('/forecast/')
return render(request,'result_links.html',{'content':'frcst_history.csv'})