[models.py]
import datetime
from flask_bcrypt import generate_password_hash
from flask_login import UserMixin
from peewee import *
DATABASE = SqliteDatabase('social.db')
class User(UserMixin, Model):
username = CharField(unique=True)
email = CharField(unique=True)
password = CharField(max_length=100)
joined_at = DateTimeField(default=datetime.datetime.now)
is_admin = BooleanField(default=False)
class Meta:
database = DATABASE
order_by = ('-joined_at',)
@classmethod
def create_user(cls, username, email, password, admin=False):
try:
cls.create(
username=username,
email=email,
password=generate_password_hash(password),
is_admin=admin
)
except IntegrityError:
raise ValueError("User already exists")
def initialize():
DATABASE.connect()
DATABASE.create_tables([User], safe=True)
DATABASE.close()
[forms.py]
from flask_wtf import Form
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Regexp, ValidationError, Email, Length, EqualTo
from models import User
def name_exists(form, field):
if User.select().where(User.username == field.data ).exists():
raise ValidationError('User with that name already exists!')
def email_exists(form, field):
if User.select().where(User.email == field.data ).exists():
raise ValidationError('User with that email already exists!')
class RegisterForm(Form):
username = StringField(
'Username',
validators = [
DataRequired(),
Regexp(
r'^[a-zA-Z0-9_]+$',
message="Only letters, numbers and underscores are allowedself."
),
name_exists
])
email = StringField(
'Email',
validators = [
DataRequired(),
Email(),
email_exists
])
password = PasswordField(
'Password',
validators = [
DataRequired(),
Length(min=2),
EqualTo('password2', message='Passwords must match!')
])
password2 = PasswordField(
'Confirm Password',
validators = [DataRequired()]
)
class LoginForm(Form):
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
[app.py]
from flask import Flask, g, render_template, redirect, url_for, flash
from flask_bcrypt import check_password_hash
from flask_login import LoginManager, login_user, logout_user, login_required
import forms
import models
DEBUG = True
PORT = 8000
HOST = '0.0.0.0'
app = Flask(__name__)
app.secret_key = 'jnkla@sdioa!sdjoo^paud&1293*hoads.ln10'
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
@login_manager.user_loader
def load_user(userID):
try:
models.User.get(models.User.id == userID)
except models.DoesNotExist:
return None
@app.before_request
def before_request():
"""Connect to the database before each request"""
g.db = models.DATABASE
g.db.connect()
@app.after_request
def after_request(response):
"""Close the database connection after each request"""
g.db.close()
return response
@app.route('/register', methods=['POST', 'GET'])
def register():
form = forms.RegisterForm() #Create form instance with validated values
if form.validate_on_submit(): #If all submitted data is valid
flash("You have been registered successfully!", "success")
models.User.create_user(
username=form.username.data,
email=form.email.data,
password=form.password.data,
)
return redirect(url_for('index'))
return render_template('register.html', form=form)
@app.route('/login', methods=['GET', 'POST'])
def login():
form = forms.LoginForm()
if form.validate_on_submit():
try:
user = models.User.get(models.User.email == form.email.data)
except models.DoesNotExist:
flash("Your email does not match your password!", "error")
else:
if check_password_hash(user.password, form.password.data):
login_user(user)
flash("You've been logged in successfully", "success")
return redirect(url_for('index'))
else:
flash("Your email does not match your password!", "error")
return render_template('login.html', form=form)
@app.route('/logout')
@login_required
def logout():
logout_user()
flash("You've successfully logged out", "success")
return redirect(url_for('index'))
@app.route('/')
def index():
return "Hey!"
if __name__ == '__main__':
models.initialize()
try:
models.User.create_user(
username='basharghadanfar',
email='10.tens@gmail.com',
password='123456',
admin=True
)
except ValueError:
pass
app.run(debug=DEBUG, port=PORT, host=HOST)
[macros.html]
{% macro render_field(field) %}
<div class="field">
{{ field(placeholder=field.label.text) }}
{% if field.errors %}
{% for error in field.errors %}
<div class="notification error">{{error}}</div>
{% endfor %}
{% endif %}
</div>
{% endmacro %}
[register.html]
{% from 'macros.html' import render_field %}
<form method="POST" action="" class="form">
{{ form.hidden_tag() }}
{% for field in form %}
{{ render_field(field) }}
{% endfor %}
<button type="submit" id="submit">Register!</button>
</form>
[login.html]
{% from 'macros.html' import render_field %}
<form method="POST" action="" class="form">
{{ form.hidden_tag() }}
{% for field in form %}
{{ render_field(field) }}
{% endfor %}
<button type="submit" id="submit">Login!</button>
</form>