0

I've setup a database and an app using flask and sqlalchemy, the get request is working fine, but the post request doesn't work at all, please support me here if you can, below you will have the code which is just a small part of my project, the get request is working fine but the post no.

Data base setup


from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy import create_engine
from passlib.apps import custom_app_context as pwd_context
import random, string
from itsdangerous import(TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired)

Base = declarative_base()


class Relation(Base):
    __tablename__ = 'relation'

    id = Column(Integer, primary_key=True)
    base_user_first = Column(String(250), nullable=False)
    base_user_second = Column(String(250), nullable=False)
    relation = Column(String(250), nullable=False)
    reverse_relation = Column(String(250), nullable=False)


    @property
    def serialize(self):
        return {
            'base_user_first': self.base_user_first,
            'id': self.id,
            'base_user_second': self.base_user_second,
            'relation': self.relation,
            'reverse_relation': self.reverse_relation,
          }

    


# creating the DB.
engine = create_engine('sqlite:///myneighbour.db')
Base.metadata.create_all(engine)

app code

from database_setup import Base, Relation
from flask import Flask, jsonify, request, url_for, abort, g
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy import create_engine

from flask_httpauth import HTTPBasicAuth

from flask import session as login_session
import random
import string
from oauth2client.client import flow_from_clientsecrets
from oauth2client.client import FlowExchangeError
import httplib2
import json
from flask import make_response
import requests


auth = HTTPBasicAuth()


engine = create_engine('sqlite:///myneighbour.db')

Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
app = Flask(__name__)






@app.route('/relation/<int:relation_id>/JSON')
def relationJSON(relation_id):
    relation = session.query(Relation).filter_by(id=relation_id).one()
    items = session.query(Relation).filter_by(
        relation_id=relation_id).all()

    return jsonify(Relation=[i.serialize for i in items])



# view all the relations
@app.route('/relation/JSON')
def relationsJSON():
    relations = session.query(Relation).all()
    return jsonify(relations=[r.serialize for r in relations])



# Create a new Relation


@app.route('/relation/new/', methods=['GET', 'POST'])
def newRelation():
    # if 'username' not in login_session:
    #     return 405
    if request.method == 'POST':
        newRelation = Relation(
            base_user_first=request.form['base_user_first'],
            base_user_second=request.form['base_user_second'],
            relation=request.form['relation'],
            reverse_relation=request.form['reverse_relation'])
        session.add(newRelation)
        #flash('New Facility %s Successfully Created' % newFacility.name)
        session.commit()
        return jsonify (newRelation)

# Edit a Relation


@app.route('/relation/<int:relation_id>/edit/', methods=['GET', 'POST'])
def editRelation(relation_id):
    editedRelation = session.query(
        Relation).filter_by(id=relation_id).one()
    # if 'username' not in login_session:
    #     return 405
    # if editedFacility.user_id != login_session['user_id']:
    #     return "<script>function myFunction() {alert('You are not authorized \
    #     to edit this restaurant. Please create your own restaurant in order to\
    #     edit.');}</script><body onload='myFunction()'>"
    if request.method == 'POST':
        if request.form['base_user_first']:
            editedRelation.base_user_first = request.form['base_user_first']

        if request.form['base_user_second']:
            editedRelation.base_user_second = request.form['base_user_second']

        if request.form['relation']:
            editedRelation.relation = request.form['relation']

        if request.form['reverse_relation']:
            editedRelation.reverse_relation = request.form['reverse_relation']



            #flash('Restaurant Successfully Edited %s' % editedRestaurant.name)
            return jsonify(editedRelation)
    # else:
    #     return render_template(
    #         'editRestaurant.html', restaurant=editedRestaurant
    #         )


# Delete a relation
@app.route('/relation/<int:relation_id>/delete/', methods=['GET', 'POST'])
def deleteRelation(relation_id):
    relationToDelete = session.query(
        Relation).filter_by(id=relation_id).one()
    # if 'username' not in login_session:
    #     return 405
    # if facilityToDelete.user_id != login_session['user_id']:
    #     return "<script>function myFunction() {alert('You are not authorized \
    #     to delete this restaurant. Please create your own restaurant in order \
    #     to delete.');}</script><body onload='myFunction()'>"
    if request.method == 'POST':
        session.delete(relationToDelete)
        #flash('%s Successfully Deleted' % restaurantToDelete.name)
        session.commit()
        return ("the relation has been deleted")

if __name__ == '__main__':
    app.debug = True
    #app.config['SECRET_KEY'] = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(32))
    app.run(host="0.0.0.0", port=5000, debug=True)

and here is what I receive when I make the post request through postman by using the /relation/new endpoint

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>The browser (or proxy) sent a request that this server could not understand.</p>
  • You've defined (some of) your routes with a trailing slash e.g. `'/relation//edit/'`. As Flask treats routes with and without trailing slashes as different URLs, try adding the trailing slash to your request. – PGHE Jul 02 '20 at 01:13
  • I'm trying but still not working – Mahmoud Gamal Jul 02 '20 at 01:35
  • Are you posting raw json or are you posting form-data? You have your route set up to read form data. – Steffen Andersland Jul 02 '20 at 01:48
  • Both request.form and request.jso.get give me the same thing, I'm posting raw json with the request.jso.get and nothing works – Mahmoud Gamal Jul 02 '20 at 02:35

2 Answers2

0

Replace all occurrences of request.form['base_user_first'] and the like to request.form.get('base_user_first')

Form sending error, Flask

0

You are receiving a Bad Request error from the server. This implies that your frontend(HTML form) is not sending the expected parameters to the server. For example, if your server is expecting field data from client via post like this:

@app.route('/user', methods=["GET", "POST"])
def userdata():
    name = request.form['name']
    email = request.form['email']
    ....

And your front end sends something like this:

fetch('/users', {
  method: 'POST',
  body: {
     nam: "Typo in name",
     email: "email@somethig.com"
  },
})

The server expects name but the frontend code sent **nam** which will generate a Bad Request(400) error. Bottom line is, make sure all request data from the frontend matches the ones expected by the server.