I'm sending data via AngularJS POST request:
$http.post('/process', { 'uid': uid, 'action': action }).success(function(response) {
console.log(response);
});
And trying to get sended values in Flask
#app.route('/process', methods = ['POST'])
def process():
return json.dumps({ 'data': request.form.get('uid', 'EMPTY') })
And Flask returns back {"data": "EMPTY"} response. request.form is empty. I've tried to get data from request.data, but it's in strange format there.
I'm learning Python and Flask so I want to do this work with native library, without any other packages right now.
get_json() method helps me
#app.route('/process', methods = ['POST'])
def process():
return json.dumps({ 'data': request.get_json().get('uid') })
If you want to get the data via request.form, you need to have angular send it differently. See this question for details: How can I post data as form data instead of a request payload?
Make sure Content-Type is application/json
Here's a tutorial series on using Flask and AngularJS together - http://tutsbucket.com/tutorials/building-a-blog-using-flask-and-angularjs-part-1/
Hope you'll find it useful.
Related
I have the following python code in my Django views.py, the code takes in a JSON body and send the extracted DATA to another API endpoint, I have simplified the code here.
How do I enable csrf such that it will send the token back to the caller for this method? I am calling this from postman.
#csrf_protect
def validate_booking(request):
if request.method != "POST":
return HttpResponseServerError("Invalid HTTP method")
body = json.loads(request.body)
booking_details = body["booking_details"]
DATA = {
"name": booking_details["name"],
"nric": booking_details["nric"],
"booking_id": booking_details["booking_id"]
}
return HttpResponse(status="200")
This site directs to put this piece of code in my method. But what is "a_template.html"?
https://docs.djangoproject.com/en/4.1/ref/csrf/
#csrf_protect
def my_view(request):
c = {}
# ...
return render(request, "a_template.html", c)
This isn't an easy thing to do as CSRF is 2 steps thing
There is a value that is passed to the client and it is saved to the session on the server.
When a POST request is received, the client shall send this as csrfmiddlewaretoken in the body and the server will check the value against the stored one in the server's session.
So this isn't feasible to be done in APIs as you require session Management which is not of REST API implementations.
Thanks for your reply. I managed to find a solution by doing the following:
Create a new GET method that will generate the session CSRF token using python
Instead of using render which expects a HTML template file, I used JsonResponse(data) to return in JSON format directly
In my postman app which I am making the POST request with the X-CSRFToken in the header, I will first make a GET request to the new method I created in step 1 to retrieve the token and store it as an environment variable
The following is the GET method sample:
from django.http import JsonResponse
def get_csrf_token(request):
csrf_token = csrf(request)['csrf_token']
data = {'csrf_token': csrf_token}
return JsonResponse(data)
I have an edit-button on my Site, that will do a POST-Request and then I want to be redirected to new.html, that contains a form, that holds my POST data.
The POST request in my js-file:
async function onEditBtn() {
// find correct entry in schedule
const data = schedule.find(meeting => meeting.id == rowIdOfContextMenu);
rowIdOfContextMenu = -1;
const response = await fetch("editmeeting", {
method: 'POST',
body: data});
}
The receiving Flask-route:
#app.route('/editmeeting', methods=['POST'])
def edit():
data = request.get_json()
print(data)
return render_template('new.html', data)
POST request is succesful, but I am not getting redirected to new.html.
If I use window.location.href = "<route to my edit page>"; or window.location.replace(); on js side using the response I get from the POST request, my edit page won't get the POST-data.
EDIT:
What I was looking for was window.location.href with POST instead of GET.
I ended up using Flask's session object. Did a POST request to /editmeeting, saved the POST-data in a session object, then manually redirected my page to another route rendering new.html using window.location.href in my js-code, and used the data stored in the session.
Thank you for your aswers!
You could add GET method to this function
#app.route('/editmeeting', methods=['GET', 'POST']
or add this to your imports
from flask import Flask, redirect, url_for
and change the return of the function to something like this (only works when 'new' is indeed a function in your app.
return redirect(url_for('new'))
I am currently stuck with POST requests in Django. I am trying to send a POST request from an external applications such as smartphones or Postman (not forms) to the rest framework. Get requests work just fine.
I went through many posts but couldn't resolve my issue. I tried to use request.body but always get an empty response. I used print(response.body) to print the output to the console and only get b'' back.
class anyClass(APIView):
def post(self, request):
print(request.body)
return Response({"id": 'anyClass',
"data": '1234',
})
How would I get the data from my request?
My post request sent with Postman:
http://127.0.0.1:8000/test/v2/Api/anyClass?qrcode=100023&date=2018-11-27&time=08:00:00&value_1=17
You can get the response in request.data:
class anyClass(APIView):
def post(self, request):
print(request.data)
return Response({"id": 'anyClass',
"data": '1234',
})
Please see the documentation for details.
Update
I think you are making wrong kind of usage of postman. Please see the screen shot regarding how to use it:
I'm working on a Flask example that takes blog posts and adding them to a database through a RESTful service.
Prior to implementing the RESTful service, I was adding blog posts to a local database by doing the following:
#main.route('/', methods=['GET', 'POST'])
def index():
form = PostForm()
if current_user.can(Permission.WRITE_ARTICLES) and \
form.validate_on_submit():
post = Post(body=form.body.data,
author=current_user._get_current_object())
db.session.add(post)
return redirect(url_for('.index'))
Now that I've gotten to the RESTful service section, the following to_json() and from_json() functions have been to the Post model:
//Convert a post from JSON
//Class Post(db.Model)
def to_json(self):
json_post = {
'url': url_for('api.get_post', id=self.id, _external=True),
'body': self.body,
'body_html': self.body_html,
'timestamp': self.timestamp,
'author': url_for('api.get_user', id=self.author_id,
_external=True),
'comments': url_for('api_get_post_comments', id=self.id,
_external=True),
'comment_count': self.comments.count()
}
return json_post
//Create a blog post from JSON
//Class Post(db.Model)
#staticmethod
def from_json(json_post):
body = json_post.get('body')
if body is None or body == '':
raise ValidationError('post does not have a body')
return Post(body=body)
The following inserts a new blog post in the database:
//POST resource handler for posts
#api.route('/posts/', methods=['POST'])
#permission_required(Permission.WRITE_ARTICLES)
def new_post():
post = Post.from_json(request.json)
post.author = g.current_user
db.session.add(post)
db.session.commit()
return jsonify(post.to_json()), 201, \
{'Location': url_for('api.get_post', id=post.id, _external=True)}
Would really appreciate it if someone could explain how these functions work with each other. My understanding of it all is that a blog post is typed up on a client device and in order to send it to the web service, the to_json function is called to convert the post to JSON. Once the web service receives the JSON version of the blog post, the from_json function is called to convert the JSON post back to its original state. Is that correct?
Edit:
Just re-read the page and I think my understanding was reverse of whats actually happening. In order to get a blog post from the web service, the to_json function is called to convert the data to JSON. Then on the client side, the from_json function is called to convert the data back from JSON.
Your edit is correct. A common response format for a REST API is JSON, which is why the the response is converted "to JSON" when returning.
Also a common header for sending data to a REST API is application/json, which is why the code converts the received data "from JSON".
I was wondering if there was a way to take something from a text box in the HTML, feed it into flask, then parse that data with Python. I was thinking this might involve some JS but I could be wrong. Any ideas?
Unless you want to do something more complicated, feeding data from a HTML form into Flask is pretty easy.
Create a view that accepts a POST request (my_form_post).
Access the form elements in the dictionary request.form.
templates/my-form.html:
<form method="POST">
<input name="text">
<input type="submit">
</form>
from flask import Flask, request, render_template
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('my-form.html')
#app.route('/', methods=['POST'])
def my_form_post():
text = request.form['text']
processed_text = text.upper()
return processed_text
This is the Flask documentation about accessing request data.
If you need more complicated forms that need validation then you can take a look at WTForms and how to integrate them with Flask.
Note: unless you have any other restrictions, you don't really need JavaScript at all to send your data (although you can use it).
Declare a Flask endpoint to accept POST input type and then do necessary steps. Use jQuery to post the data.
from flask import request
#app.route('/parse_data', methods=['GET', 'POST'])
def parse_data(data):
if request.method == "POST":
#perform action here
var value = $('.textbox').val();
$.ajax({
type: 'POST',
url: "{{ url_for('parse_data') }}",
data: JSON.stringify(value),
contentType: 'application/json',
success: function(data){
// do something with the received data
}
});
All interaction between server(your flask app) and client(browser) going by request and response. When user hit button submit in your form his browser send request with this form to your server (flask app), and you can get content of the form like:
request.args.get('form_name')
Assuming you already know how to write a view in Flask that responds to a url, create one that reads the request.post data. To add the input box to this post data create a form on your page with the text box. You can then use jquery to do
var data = $('#<form-id>').serialize()
and then post to your view asynchronously using something like the below.
$.post('<your view url>', function(data) {
$('.result').html(data);
});
This worked for me.
def parse_data():
if request.method == "POST":
data = request.get_json()
print(data['answers'])
return render_template('output.html', data=data)
$.ajax({
type: 'POST',
url: "/parse_data",
data: JSON.stringify({values}),
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function(data){
// do something with the received data
}
});