Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialMatthew McElwee
16,545 PointsTrouble with POST (Flask Rest API)
I have followed the instructions in the video. Get requests are working great, however I can't get post data to send. I keep getting an error that says: "The browser (or proxy) sent a request that this server could not understand."
Any help would be great.
2 Answers
David Lin
35,864 PointsCan you post your code?
Here's my courses.py and reviews.py, and the POST works fine:
courses.py :
from flask import jsonify, Blueprint, abort
from flask_restful import (Resource, Api, reqparse, url_for,
inputs, fields, marshal, marshal_with)
import models
course_fields = {
'id': fields.Integer,
'title': fields.String,
'url': fields.String,
'reviews': fields.List(fields.String)
}
def add_reviews(course):
course.reviews = [url_for('resources.reviews.review', id=review.id)
for review in course.review_set]
return course
def course_or_404(course_id):
try:
course = models.Course.get(models.Course.id==course_id)
except models.Course.DoesNotExist:
abort(404)
else:
return course
class CourseList(Resource):
def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument(
'title',
required=True,
help='No course title provided',
location=['form', 'json']
)
self.reqparse.add_argument(
'url',
required=True,
help='No course URL provided',
location=['form', 'json'],
type=inputs.url
)
super().__init__()
def get(self):
courses = [marshal(add_reviews(course), course_fields)
for course in models.Course.select()]
return {'courses': courses}
@marshal_with(course_fields)
def post(self):
args = self.reqparse.parse_args()
course = models.Course.create(**args)
return (add_reviews(course), 201,
{'Location': url_for('resources.courses.course', id=course.id)})
class Course(Resource):
def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument(
'title',
required=True,
help='No course title provided',
location=['form', 'json']
)
self.reqparse.add_argument(
'url',
required=True,
help='No course URL provided',
location=['form', 'json'],
type=inputs.url
)
super().__init__()
@marshal_with(course_fields)
def get(self, id):
return add_reviews(course_or_404(id))
@marshal_with(course_fields)
def put(self, id):
args = self.reqparse.parse_args()
course = course_or_404(id)
query = course.update(**args)
query.execute()
course = course_or_404(id)
return (course, 200,
{'Location': url_for('resources.courses.course', id=id)})
def delete(self, id):
course = course_or_404(id)
query = course.delete()
query.execute()
return '', 204, {'Location': url_for('resources.courses.courses')}
courses_api = Blueprint('resources.courses', __name__)
api = Api(courses_api)
api.add_resource(
CourseList,
'/api/v1/courses',
endpoint='courses'
)
api.add_resource(
Course,
'/api/v1/courses/<int:id>',
endpoint='course'
)
reviews.py :
from flask import jsonify, Blueprint, abort
from flask_restful import (Resource, Api, reqparse, inputs, url_for,
fields, marshal, marshal_with)
import models
review_fields = {
'id': fields.Integer,
'for_course': fields.String,
'rating': fields.Integer,
'comment': fields.String(default=''),
'created_at': fields.DateTime
}
def add_course(review):
review.for_course = url_for('resources.courses.course', id=review.course.id)
return review
def review_or_404(review_id):
try:
review = models.Review.get(models.Review.id==review_id)
except models.Review.DoesNotExist:
abort(404)
else:
return review
class ReviewList(Resource):
def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument(
'course',
type=inputs.positive,
required=True,
help='No course provided',
location=['form', 'json']
)
self.reqparse.add_argument(
'rating',
required=True,
type=inputs.int_range(1,5),
help='No rating provided',
location=['form', 'json'],
)
self.reqparse.add_argument(
'comment',
required=False,
nullable=True,
location=['form', 'json'],
default=''
)
super().__init__()
def get(self):
reviews = [marshal(add_course(review), review_fields) for review in models.Review.select()]
return {'reviews': reviews}
@marshal_with(review_fields)
def post(self):
args = self.reqparse.parse_args()
review = models.Review.create(**args)
return (add_course(review), 201,
{'Location': url_for('resources.reviews.review', id=review.id)})
class Review(Resource):
def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument(
'course',
type=inputs.positive,
required=True,
help='No course provided',
location=['form', 'json']
)
self.reqparse.add_argument(
'rating',
type=inputs.int_range(1, 5),
required=True,
help='No rating provided',
location=['form', 'json']
)
self.reqparse.add_argument(
'comment',
required=False,
nullable=True,
location=['form', 'json'],
default=''
)
super().__init__()
@marshal_with(review_fields)
def get(self, id):
return add_course(review_or_404(id))
@marshal_with(review_fields)
def put(self, id):
args = self.reqparse.parse_args()
review = review_or_404(id)
query = review.update(**args)
query.execute()
review = add_course(review_or_404(id))
return (review, 200,
{'Location': url_for('resources.reviews.review', id=id)})
def delete(self, id):
review = review_or_404(id)
query = review.delete()
query.execute()
return '', 204, {'Location': url_for('resoures.reviews.reviews')}
reviews_api = Blueprint('resources.reviews', __name__)
api = Api(reviews_api)
api.add_resource(
ReviewList,
'/reviews',
endpoint='reviews'
)
api.add_resource(
Review,
'/review/<int:id>',
endpoint='review'
)
Liliana Carnival
39 PointsHi the post does not work for me , can anyone help me , I used the code above, but I get { "message": { "title": "No course title provided" } }
Thanks