-3

I did all that was stated on tutorial point (just copied and pasted), but when I tried to add a student entry,i.e. ‘Add Student’ it gives

Bad Request The browser (or proxy) sent a request that this server could not understand.

Please advise if there is anything wrong with the tutorial.

It failed at this line within def new(), in app.py:

 student = students(request.form['name'], request.form['city'], request.form['addr'], request.form['pin'])

Whoever is flagging this down. Note that it is the tutorial that is filled with typos and wrong indentations. I am only a student. Shut this down and I will learn nothing.

Ref: http://www.tutorialspoint.com/flask/flask_sqlalchemy.htm

from flask import Flask, request, flash, url_for, redirect, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.sqlite3'
app.config['SECRET_KEY'] = "random string"

db = SQLAlchemy(app)

class Students(db.Model):
    id = db.Column('student_id', db.Integer, primary_key = True)
    name = db.Column(db.String(100))
    city = db.Column(db.String(50))
    addr = db.Column(db.String(200)) 
    pin = db.Column(db.String(10))

    def __init__(self, name, city, addr,pin):
        self.name = name
        self.city = city
        self.addr = addr
        self.pin = pin

    @app.route('/')
    def show_all():
        return render_template('show_all.html', Students = Students.query.all() )

    @app.route('/new', methods = ['GET', 'POST'])
    def new():
        if request.method == 'POST':
            if not request.form['name'] or not request.form['city'] or not request.form['addr']:
                flash('Please enter all the fields', 'error')
        else:
            print "1";
            student = Students(request.form['name'], request.form['city'], request.form['addr'], request.form['pin'])

            print "1";
            db.session.add(student)
            print "1";
            db.session.commit()
            print "1";
            flash('Record was successfully added')
            print "=======>>>>>>>>>";
            return redirect(url_for('show_all'))
        return render_template('new.html')

if __name__ == '__main__':
    db.create_all()
    app.run(debug = True)
Ursa Major
  • 851
  • 7
  • 25
  • 47

2 Answers2

5

The tutorial has an indentation problem in the student class. The constructor code should be indented one level so it becomes a method of the student class.

Corrected code: (note the indent of "def init(self, name, city, addr,pin):" in the code below)

class students(db.Model):
   id = db.Column('student_id', db.Integer, primary_key = True)
   name = db.Column(db.String(100))
   city = db.Column(db.String(50))
   addr = db.Column(db.String(200)) 
   pin = db.Column(db.String(10))

   def __init__(self, name, city, addr,pin):
      self.name = name
      self.city = city
      self.addr = addr
      self.pin = pin

The reason is, if that indent is not there, python will not see this function as a constructor of the student class. So the constructor with the matching number of arguments is not found, resulting in the error.

Davy
  • 1,720
  • 1
  • 19
  • 42
  • Looks like there could be other problems as well. – Ursa Major Jul 30 '16 at 07:52
  • Even the student object code is not indented properly, if you check it shows _E111 - indentation is not a multiple of four_ so the error arises from the request.form. – simanacci Jul 30 '16 at 08:07
  • 1
    Could be, depending on how the code is copy/pasted into an editor. Make sure to use a python-aware IDE such as PyCharm or other: https://wiki.python.org/moin/IntegratedDevelopmentEnvironments – Davy Jul 30 '16 at 08:10
  • The page on the link does show that the indentation is wrong. – Ursa Major Jul 30 '16 at 08:15
  • Thank you for pointing out on the indentation. However, there are still other errors. – Ursa Major Jul 30 '16 at 08:16
  • I traced that there is a problem with ` student = students(request.form['name'], request.form['city'], request.form['addr'], request.form['pin'])` – Ursa Major Jul 30 '16 at 08:19
  • That is invoking the student constructor. For me "add user" works fine, just changing the indentation mentioned above. Cross check all indentation: 4 spaces for each level as explained here: https://www.python.org/dev/peps/pep-0008/#indentation – Davy Jul 30 '16 at 08:25
0

It's not following the class naming convention. The student class should use Camel case. Try this:

student = Students(request.form['name'], request.form['city'],
        request.form['addr'], request.form['pin'])

The SQLAlchemy model should also follow the same, Students not students.

class Students(db.Model):
    id = db.Column('student_id', db.Integer, primary_key = True)
    name = db.Column(db.String(100))
    city = db.Column(db.String(50))  
    addr = db.Column(db.String(200))
    pin = db.Column(db.String(10))

Edit
Given Iron Fist's comment that the same code is running okay for him, its very likely that there is a mistake or typo in your code for creating a new student object. Even if you have copy pasted the code, an error may occur when typing the code assuming you did not use CTRL-V or when pasting it. According to the Flask docs:

What happens if the key does not exist in the form attribute? In that case a special KeyError is raised. You can catch it like a standard KeyError but if you don’t do that, a HTTP 400 Bad Request error page is shown instead. So for many situations you don’t have to deal with that problem.

Therefore if @IronFist ran the same code without a problem, but for you its returning a bad response error which as explained above is as a result of a missing key in the form, then its most likely a mistake on the code you are running. Also read this and this they are similar to your question.

Community
  • 1
  • 1
simanacci
  • 2,197
  • 3
  • 26
  • 35
  • Not following the naming convention will not cause an error. – Davy Jul 30 '16 at 08:29
  • @Davy its possible he may have _Students_ in the class and _students_ while creating the new student or vice versa. – simanacci Jul 30 '16 at 08:34
  • @UrsaMajor the bad request error means there is something wrong with your form dictionary, there is a mismatch or missing item in your `keys`. – simanacci Jul 30 '16 at 08:56
  • I think the tutorial is filled with so much error that it is unusable. The author has been very irresponsible to misguide beginners like us. – Ursa Major Jul 30 '16 at 13:16
  • I've edited my answer with links to similar questions, plus @IronFist ran the same code without a problem. Given the bad response error, there is a problem in the dict that contains the keys & args. Assuming you typed the same code and did not actually copy and paste, that is where the error originates from, you may have missed something while typing. – simanacci Jul 30 '16 at 14:10