flask error sending POST and GET to same function, - python

This is a function which (in a GET request) receives a case_url and case_key and serves the corresponding case (using mongoDB) to a html template called detail_case.
Im trying to add a feature where when a form is filled(on this same page detail_case) and it is submitted, it should submit a POST request to the same function and the code under 'if request.method=="POST"' should get executed.
#app.route('/case/<case_url>/<case_key>', methods=["GET","POST"])
def serve_case(case_url,case_key):
"""for saving a comment in db.comments"""
if request.method == "POST":
text=request.form['comment_text']
#code which inserts it in the database
return redirect(url_for('serve_case', \
case_url=case_url,\
case_key="Highlights"))
"""
Function serves the case as per the key indicated in the URL
"""
#corresponding code here which fills values of variables and sends it to another page
return render_template('detail_case.html')
The problem is that I don't think the POST request is ever executed. This is the html code on the template page detail_case-
<textarea placeholder="Please enter your comments here" action="{{ url_for('serve_case',case_url=case_url,case_key=case_key)}}" method="POST" name="comment_text" rows="6"></textarea><br />
The problem i think is the action field. I don't know how should I send the variable comment_text to my function. Infact, the code under POST does not get executed when I submit.
Basically the issue is that during a GET request, it sends 2 variables which are needed in the parameters of the function serve_case. During my POST request, well, I don't know how to exactly frame the action field. If I send no parameters, its an error. If I don't send it to the same function, then how will it execute the POST code? Could someone please suggest sumthing?
i'm pretty new to flask, i'm editing someone else's code

You need to submit the POST request (for example through form) like below:
<form action="{{ url_for('serve_case',case_url=case_url,case_key=case_key)}}" method="POST">
<input type="text" placeholder="Please enter your comments here">
<input type="submit" name="comment_text" rows="6"><br />
</form>

Related

How to Carry Flask Variable to JavaScript File

New Programmer Here
So I'm working on a contact form and when I click send I want a message to appear and disappear.
The problem is if some fields were left empty I obviously wouldn't want to show the message because it didn't actually send.
So I was trying to only show the message if the server makes a POST request as opposed to a GET
request because then I know the information was actually stored.
Therefore I used the "post" variable in my html, used jquery to target it and store it in the variable method. But for some reason the if statement isn't being triggered when the the variable "method" does equal "POST"
Tried to explain as best as possible as this is my first time posting.
I know the method value is "POST" when I hit send because it populates on html and I get an alert saying POST
Python Code
#app.route("/contact" , methods=['GET', 'POST'])
def contact():
meth = request.method
return render_template("contact.html",page=x, post=meth)
HTML CODE
<div id="method">
{{post}}
</div>
<div class="submit-message">
<p class="message">THANKS FOR YOUR MESSAGE! </p>
</div>
JS Code
$(document).ready(function(){
var method = $("#method").html();
$("#method").hide();
alert(method)
if (method == "POST"){
$(".message").show();
alert(method);}
else{
$(".message").hide();
}
});

Button click in HTML to update SQLAlchemy db in Flask

I'm trying to update a database value called ''favorites'' for the logged in user of a Flask web app using a button click. Essentially, the favorites column is a single string that looks like this: Apples, Bananas, Oranges where on the button click, I would want to append a value (say Cherries) by breaking apart the string into a list in my #app.routes(), appending the value, and rejoining it back into a string before committing the changes. I'm not sure what the proper way is to do this, here's what I have:
HTML snippet
<button action="{{ url_for('add') }}" method="post" type="submit">Favorite</button>
#app.routes()
#app.route('/add', methods=['POST'])
def add():
star_faves = current_user.favorites
star_faves_list = star_faves.split(', ')
star_faves_list.append('Cherries')
', '.join(star_faves_list)
current_user.favorites = star_faves_list
db.session.commit()
return render_template('add.html')
The problem is that I don't really understand how the HTML is communicating with Python/Jinja, if anybody can help clear that up I would greatly appreciate it.
It looks like you have some elements confused.
If you want to submit a POST request to the /add page, the easiest way is to create a form. (Buttons do not have an action or method attribute, forms do.) When you create the form, you also specify the HTTP method to use when submitting the form. So in your case, it should look something like this:
<form action="{{ url_for('add') }}" method="POST">
<input type="submit" value="Favorite">
</form>
You can use a button instead of an input with type submit, they are interchangeable.
If you don't want the page to reload while submitting the request, a more advanced technique you can use with JavaScript is something called AJAX.
This example code sends the same POST request to the /add page:
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
// this method gets called if the state of the request changes (it succeeds of fails)
// you will probably want to update your page accordingly here
};
request.open('POST', '/add');
request.send();

Using flask form result to generate a URL?

I am creating an app that does some analysis, given a user enters in some IDs into the form. For example, if a user types 12345, 23456 into the TextField form, the app will run some analysis on these IDs and then display the results. My problem is that currently, when the user clicks "Submit" and the data analysis completes, it always redirects the user to www.website.com/results. I need to create unique url's like www.website.com/results/12345+23456 so that 1) I can have multiple users and 2) users can send this link to people to re-generate the analysis.
Now, there are some questions on StackOverflow that are similar to my question but they are not the same and did not help me. So first, let me show some code before discussing that.
I have a home page which contains the the form:
<div>
<form action="https://website.com/results/" class="form-inline" method="post">
<div class="form-group">
<label for="PubmedID">Pubmed ID(s)</label>
<input type="text" class="form-control" id="PubmedID" name="pmid" value="{{request.form.pmid}}">
</div>
<button type="submit" id= "myButton" class="btn btn-default" data-toggle="modal" data-target="#myModal">Submit</button>
</form>
</div>
As you can see, the value for the form is request.form.pmid. My Flask-Wtform for this is here:
class pmidForm(Form):
pmid = TextField('PubmedID')
Since the action of this form points towards website.com/results that triggers my Flask function to be called:
#app.route('/results/', methods=["POST"])
def results():
form = pmidForm()
try:
if request.method == 'POST':
#entry = request.form or request.data doesn't help me...
entry = form.pmid.data #This is the user input from the form!
# DO LOTS OF STUFF WITH THE ENTRY
return render_template('results.html')
except Exception as e:
return(str(e))
As you can see I am using POST and form.pmid.data to get the data from the textfield form.
Again, I don't want to just redirect to /results, I'd like to expand on that. I tried to modify my form so that the form action pointed to https://website.com/results/{{request.form.pmid}}/ and then update the results function to be
#app.route('/results/<form_stuff>', methods=["POST"])
def results(form_stuff):
But this never worked and would re-direct me to a 404 not found page. Which I believe makes sense because there is no form data in the action when the HTML is first rendered anyway.
Now, the other post that mine is similar to is: Keeping forms data in url with flask, but it quite doesn't answer or solve my problem. For tthis post, the key point that people made was to use POST (which I already do), and to obtain and return the data with return request.args['query']. For me, I'm already processing the form data as I need to, and I have my return render_template() exactly how I want it. I just need to add something to the results URL so that it can be unique for whatever the user put into the form.
What do I need to add to my form in the html and to my Flask /results function in order to have the form data added into the URL? Please let me know if there's any other information I can provide to make my problem more clear. I appreciate the help! Thanks
This isn't really a question about Flask.
If you want the data to show in the URL when you submit the form, you should use method="get" rather than "post". Then the URL will be in the form https://website.com/results/?pmid=12345.

Create a Flask Search Bar that Inserts URI Variable with url_for()

I have a Flask site that has a 'search bar' where you type in the location ID of a particular location and then click Submit to be taken to the page for that location, if it exists. Here's the current form action:
<form id="locationinfo" action="{{ url_for('location') }}">
When you click Submit you are taken to /location?info=SITEID and that works just fine. What I want to do is change this behavior slightly so that when a user clicks Submit they are taken to /location/SITEID/ instead. I have the decorator set up in my main Flask routes file, but I'm struggling to put the pieces together to get this simple form together.
#app.route("/location/<locationid>/")
def locations(locationid):
...
return locationid
Any direction would be greatly appreciated!
[Edit with current full form code]
#app.route("/location")
def location():
location_id = request.args.get("info")
<form id="info" action="{{ url_for('location') }}">
<input type="text" name="info" id="locationfield">
<button type="submit">Go!</button>
</form>
You can't change how HTML forms submit their fields, they will always be in the query string or body (POST). One option is to use JavaScript to override the submit event to perform your own submit and re-render with the results.
A simpler solution is to redirect to the nice url after submit. This keeps the "search" action separate from the "show" action (even if they are handled by the same view).
#app.route('/location/')
#app.route('/location/<int:id>/')
def location(id=None):
# redirect to the second form if the id wasn't in the path
# raises 400 error if id wasn't in the query
if id is None:
return redirect(url_for('location', id=request.args['info']))
# id is in the path, continue
...
You can expand this later if you want to search by something besides id. Perform the search then redirect to the found id.

tornado URL and HTML form

I'm using tornado and I want to Insert something to my MongoDB from values in a HTML form.
in the HTML file I have a form like this:
<form method="get" >
with 2 textbox and a submit button.
and I don't know what to set as "action"
I have a handler class with a function called "post" like bellow:
class MyHandler(tornado.web.RequestHandler):
def post(self):
name = self.get_argument("Name", "")
index = self.get_argument("Index","")
.... code for updating MongoDB
I have a file called BaseUrl.py that contains:
(/admin/edit[/]?',MyHandler )
but it seems that the "post" function in myHandler does not execute.
could you please give me some advice about how to properly set my URLs and form actions?
Change the form method to POST as you are handling in a POST request:
<form method="POST" >
You also need to provide an action if the form is served from different page, so your form should be:
<form method="POST" action="/admin/edit">
Your post method isn't called because your form specifies method="get". Change that to method="post" and it'll probably work.
If the action is empty the browser will submit the request to the current page, so if you have a get handler serving the form at the same URL you don't need to specify it.

Categories

Resources