How to build a get-form post in flask - python

Ok so I am new to flask, and want to know what objects or tools I would use to do this. I want to create a form, where the user inputs some text, clicks a submit button, then the text that they submitted is bound as a python string, and has a function run on it, and that text is then posted back onto the web page they are viewing with the return value of that function it went through. Here is an example:
html form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action = "/" method="get">
<input type="text" name="mail" size="25">
<input type="submit" value="Submit">
</form>
<textarea cols="50" rows="4" name="result"></textarea>
</body>
</html>
Then here is what I believe should be the url function should look like
#app.route('/', methods=['GET', 'POST'])
def form():
if request.method == 'GET':
input_text = request.data #step to bind form text to python string
new_text = textfunction(input_text) #running the function on the retrieved test.
return (new_text) # no idea if this is write, but returns text after modification.
What would be the best way to set this up? Would it be correct to put a variable as the value for the input html? Need some help on this.

Basically, what you want to do is have a block in your template that is only included if the variable has a value set. See the following example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action = "/" method="get">
<input type="text" name="mail" size="25">
<input type="submit" value="Submit">
</form>
{% if result %}
<textarea cols="50" rows="4" name="result">{{ result }}</textarea>
{% endif %}
</body>
</html>
and then in your python code
#app.route('/', methods=['GET', 'POST'])
def index(result=None):
if request.args.get('mail', None):
result = process_text(request.args['mail'])
return render_template('index.html', result=result)
def process_text(text):
return "FOO" + text

Related

Django returns "internal" sign in form

I try to create my own session middleware and my uauth system using Django. I've got the following code:
class CheckSessionsExistMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
...
response = self.get_response(request)
...
response.status_code = 401
response.reason_phrase = 'Unauthorized'
realm = 'some_app'
response['WWW-Authenticate'] = f'Basic real={realm}'
return response
When i set to respone header 'WWW-Authenticate' the string that contains word 'Basic', Django returns "internal" the sign in form and i do not understand.
Link to example of "internal" sign in form that Django returns: https://psv4.userapi.com/c235131/u2000021998/docs/d23/bc9d828c3755/file.png?extra=0qo4COrPeQh3mwjuRs1WoYsB3GVW8WB-Xn01jjtQz7muPVFWRqKjsm0itRqJFhOqjoYoKQGpAqWbG4xNQlJD3_kcs1u0UNct_76s6b1jv0u9oW76cnH2bGBTWWt_hpSQY-OpgxtRj_h56RPnwMZC73NRHw
Is there a way to disable this behavior?
Example of returning html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id="login_form" action="http://127.0.0.1:8000/auth/register/" method="post">
<label for="username_input">
Usesrname
</label>
<input type="text" id="username_input" name=""> <br>
<label for="password_input">
Password
</label>
<input type="text" id="password_input" style="margin-left: 10px"> <br>
<input type="submit" value="Sign in">
</form>
Is it first time? Sign up
</body>
</html>
I expected that Django just return to client the header 'WWW-Authenticate' with value 'Basic realm=some_app' and my html form without "internal" sign in form.

Print a text of textbox in HTML with Flask after pressing a button

This is my first exercise in Flask and I would like to understand what I am doing wrong here.
I want to insert a text in a textbox and then visualize it in HTML
I have already looked many answers on StackOverflow, including this:
Set a python variable in flask with a button and javascript
This is my python code:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def my_form():
return render_template('test.html')
#app.route("/", methods=['GET','POST'])
def func_test():
if request.method == 'POST':
text = request.form['Value1']
return render_template('test.html', value1=text)
if __name__ == "__main__":
app.run(port=5000, debug=True)
and this is my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form methods="POST">
<p>Login </p><br>
<p>Value1 <input type = "text" name = "Value1" /></p>
<p><input type = "submit" value = "submit" name = "submit" /></p>
</form>
input is {{value1}}
</body>
</html>
What I would like is that after the text is written in the textbox and the button is pressed, the text is printed after input is
Thanks
well, you can wrap your txt result in an if block that only shows when there is value
{% if value %}
input is {{value1}}
{% else %}
input is:
{% endif %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="POST">
<p>Login </p><br>
<p>Value1 <input type = "text" name = "Value1" /></p>
<p><input type = "submit" value = "submit" name = "submit" /></p>
</form>
input is {{value1}}
</body>
</html>
You're wanting to accept user input from an HTML form, and return that to the page. As far as I know you're going to need some kind of asynchronous Javascript (aka AJAX) to get this done.
Below is a full example modified from How to display a returned input in Flask using Ajax? for your situation.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename='script.js') }}"></script>
<p>Login </p><br>
<form action='/process' method="POST" autocomplete="off">
<div>
<p>Value1 <input type="text" name="value1" id="value1"></p>
<p><button type="submit">Submit</button></p>
</div>
</form>
<p id="input_is"></p>
</body>
</html>
Asychronous Javascript/AJAX, put this in a file called script.js in your static directory:
$(document).ready(function() {
$('form').on('submit', function(event) {
$.ajax({
data : {
value1 : $('#value1').val(),
},
type : 'POST',
url : '/process'
})
.done(function(data) {
$('#input_is').text(data['response']).show();
});
event.preventDefault();
});
});
And your Flask route:
from flask import jsonify # add to your existing import
#app.route('/process', methods=['POST'])
def process():
user_input = request.form['value1']
print(user_input) # just for debugging purposes
return jsonify({'response' : user_input})

Request.POST.get not working for me in django, returning default value

I am trying to get input from a html form in django , python code below:
def add(request):
n = request.POST.get('Username', 'Did not work')
i = Item(name=n,price=0)
i.save()
return render(request,'tarkovdb/test.html')
Second pic is my html code:
<html>
<head>
<meta charset="UTF-8"›
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384—Vkoo8x4CGs0 OPaXtkKtu6ug5T0eNV6gBiFeWPGFN9Muh0f23Q9Ifjh" crossorigin="anonymous">
<title>Tarkov Database Web App</title>
</head>
<body>
<h1>This is the page to add items</h1>
<li>List of Items in DataBase</li>
<form>
<div class="form—group">
<label for&username'> Username: </lable>
<input type&text' name='Username' id.'username'> <br><br>
</div>
<button type="submit" class="btn btn—primary">Submit</button>
</form>
You need to set your method attribute to "post" on your HTML form tag. Like this:
<form method="post">
<!-- your fields here -->
</form>
Otherwise you'll be sending a GET request, which is the default value of the method attribute.
PD.: Please paste your code, make it easy for the community to help you. Otherwise you'll get down voted.

Load file selected in html page to pandas

I am trying to automate the Winross(market research tool) tables syntax to generate Open-end tables. I need to use two excel files for this for which I am planning to use Pandas. I am not sure how to load the excel files into pandas which are selected in HTML using input type = "file".
Adding both HTML and python codes below
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>OE Tables</title>
</head>
<body>
<form class="" action="getfile" method="post" enctype="multipart/form-data">
<h1>OE Tables Generator</h1>
<h3>Select OE data:</h3>
<input type="file" name="myfile" value=""><br><br>
<input type="submit" name="" value="Upload OE File"><br><br>
<h3>Select Code-frame:</h3>
<input type="file" name="myfile" value=""><br><br>
<input type="submit" name="" value="Upload Code-frame"><br <br>
</form>
</body>
</html>
from flask import Flask, render_template, request
import pandas as pd
app = Flask(__name__)
#app.route("/")
def index():
return render_template("index.html")
#app.route('/getfile', methods=['GET', 'POST'])
def getfile():
if request.method == 'POST':
excel_file = request.files['myfile']
oedata = pd.read_excel(excel_file)
return oedata.head()
else:
result = request.args.get['myfile']
return result
Currently getting a page with below error:
Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

django render_to_response on google app engine

I am experiencing a weird issue using Django on Google App Engine. I have a file upload form defined within a django-app like this:
class ConvertForm(forms.Form):
from = forms.ChoiceField(choices=choices_from,
label='from:')
to = forms.ChoiceField(choices=choices_to,
label='to:')
class Meta:
fields = ('from','to')
And then I have in my app.views file the following:
def convert(request):
if request.POST:
form = ConvertForm(request.POST,request.FILES)
if form.is_valid():
from = form.cleaned_data['from']
to = form.cleaned_data['to']
# Redirect to a result page after post to avoid duplicates
return HttpResponseRedirect('/convert/results')
else:
form = ConvertForm()
args = {}
args.update(csrf(request))
args['form']=form
return render_to_response('convert.html',args)
The form-part of my convert.html template looks like this:
<form action="/convert/convert/" method="post" enctype="multipart/form-data">{%\
csrf_token %}
<ul>
{{ form.as_ul }}
</ul>
<input type="submit" name="submit" value="Convert">
</form>
It's supposed to be a file-upload form (hence the multipart), but I edited the form-contents for brevity.
Now, when I browse the proper url, nothing happens. I can clearly see that the correct functions are being called, since replacing the body of the convert() function with a simple
return render_to_response('convert_test.html',{'some_text':some_text})
displays the value of some_text in the browser window. Is there any additional quirks when dealing with forms within GAE that I am missing, or why isn't convert.html being rendered with the form? I should mention that all of this is on localhost, I haven't deployed it yet.
Edit: After some more fiddling around with this, it seems that maybe the source of the error is in the inheritance of templates. If I take out all django-tags {} in the convert.html, I can get the form to render correctly.
So, the question is now how do I properly set up template inheritance within GAE?
My full convert.html template looks like this:
{% extends "base.html" %}
{% block content %}
<h2>[ convert ]</h2>
<form action="/convert/convert/" method="post" enctype="multipart/form-data">{% \
csrf_token %}
<ul>
{{ form.as_ul }}
</ul>
<input type="submit" name="submit" value="Convert">
</form>
{% endblock %}
So basically redefining the content block of the base.html template. This was working perfectly before I tested it on GAE, so I can't shake the feeling that's involved somehow.
If it is relevant, my django settings.py looks like this for the templates:
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__),'..','convert','templates'),
os.path.join(os.path.dirname(__file__),'..','templates'),
)
And as I said, taking out the {}-tags from convert.html gives me the form, but rendered on its own in an otherwise completely white and empty page.
This is the contents of my base.html template
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/\
DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="Your description goes here" />
<meta name="keywords" content="your,keywords,goes,here" />
<meta name="author" content="Your Name" />
<link rel="stylesheet" type="text/css" href="/static/css/basic-minimal.css" ti\
tle="Basic Minimal" media="all" />
<title>Basic Minimal v1.2</title>
</head>
<body class="light">
<div id="wrap">
<div id="header">
<h1>[ snazzy title ]</h1>
</div>
<div id="sidebar">
<ul>
<li>[ Convert ]</li>
<li>[ Transform ]</li>
<li>[ Help ]</li>
<li>[ References ]</li>
</ul>
</div>
<div id="content">
<h2>[ more title ]</h2>
<p>Text</p>
<p>More text</p>
</div>
</div>
</body>
</html>
This works beautifully for the "title" page (even the css gets loaded), but rendering other templates as convert.html above using this as a base does not work.

Categories