Flask-SQLAlchemy nullable=False
Question:
I’m messing around with Flask and the Flask-SQLAlchemy extension to create a simple registration form. In my User class, I have the attribute “email” set to nullable=False, but when I test the form on the site without including an email, it saves the new user to the db instead of throwing an exception as I expected. Any idea why that’s happening? Thanks for looking!
Here’s the code:
from flask import Flask, url_for, render_template, request, redirect
from flaskext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/kloubi.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(80), unique=True, nullable=False)
fname = db.Column(db.String(80))
lname = db.Column(db.String(80))
def __init__(self, username, email, fname, lname):
self.username = username
self.email = email
self.fname = fname
self.lname = lname
@app.route('/')
def index():
return render_template('index.html')
@app.route('/register/', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
new_user = User(fname = request.form['name'],
lname = request.form['surname'],
email = request.form['email'],
username = request.form['username'])
db.session.add(new_user)
db.session.commit()
return redirect(url_for('index'))
return render_template('register.html')
if __name__ == '__main__':
app.debug = True
app.run(host='0.0.0.0')
Answers:
The problem is when you submit the webform without entering an email it will contain an empty string “” .. not None… and an empty string is not the same als null and it is ok to store it in the field.
I suggest using something like wtforms to validate the input of the user.
You can add a judgment if email != ''
you can use html5 attribute email directly in html. See this.
Option1: If you are defining form by yourself in HTML
Just by using the required attribute in input HTML tag will prompt the user that an input field must be filled out before submitting the form.
<form action="#">
<input type="email" name="email" required>
<input type="submit">
</form>
Option2: If you are using WTforms to define the form
Then by using validators.required() while defining form class you can achieve the same result
class MyForm(Form):
email = EmailField(u'Email', [validators.required()])
I’m messing around with Flask and the Flask-SQLAlchemy extension to create a simple registration form. In my User class, I have the attribute “email” set to nullable=False, but when I test the form on the site without including an email, it saves the new user to the db instead of throwing an exception as I expected. Any idea why that’s happening? Thanks for looking!
Here’s the code:
from flask import Flask, url_for, render_template, request, redirect
from flaskext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/kloubi.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(80), unique=True, nullable=False)
fname = db.Column(db.String(80))
lname = db.Column(db.String(80))
def __init__(self, username, email, fname, lname):
self.username = username
self.email = email
self.fname = fname
self.lname = lname
@app.route('/')
def index():
return render_template('index.html')
@app.route('/register/', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
new_user = User(fname = request.form['name'],
lname = request.form['surname'],
email = request.form['email'],
username = request.form['username'])
db.session.add(new_user)
db.session.commit()
return redirect(url_for('index'))
return render_template('register.html')
if __name__ == '__main__':
app.debug = True
app.run(host='0.0.0.0')
The problem is when you submit the webform without entering an email it will contain an empty string “” .. not None… and an empty string is not the same als null and it is ok to store it in the field.
I suggest using something like wtforms to validate the input of the user.
You can add a judgment if email != ''
you can use html5 attribute email directly in html. See this.
Option1: If you are defining form by yourself in HTML
Just by using the required attribute in input HTML tag will prompt the user that an input field must be filled out before submitting the form.
<form action="#">
<input type="email" name="email" required>
<input type="submit">
</form>
Option2: If you are using WTforms to define the form
Then by using validators.required() while defining form class you can achieve the same result
class MyForm(Form):
email = EmailField(u'Email', [validators.required()])