parent
34c6faf630
commit
2986743a8c
@ -0,0 +1 @@ |
|||||||
|
"""Tests for the app.""" |
@ -1,23 +1,31 @@ |
|||||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||||
from factory import Sequence, PostGenerationMethodCall |
"""Factories to help in tests.""" |
||||||
|
from factory import PostGenerationMethodCall, Sequence |
||||||
from factory.alchemy import SQLAlchemyModelFactory |
from factory.alchemy import SQLAlchemyModelFactory |
||||||
|
|
||||||
from {{cookiecutter.app_name}}.user.models import User |
|
||||||
from {{cookiecutter.app_name}}.database import db |
from {{cookiecutter.app_name}}.database import db |
||||||
|
from {{cookiecutter.app_name}}.user.models import User |
||||||
|
|
||||||
|
|
||||||
class BaseFactory(SQLAlchemyModelFactory): |
class BaseFactory(SQLAlchemyModelFactory): |
||||||
|
"""Base factory.""" |
||||||
|
|
||||||
class Meta: |
class Meta: |
||||||
|
"""Factory configuration.""" |
||||||
|
|
||||||
abstract = True |
abstract = True |
||||||
sqlalchemy_session = db.session |
sqlalchemy_session = db.session |
||||||
|
|
||||||
|
|
||||||
class UserFactory(BaseFactory): |
class UserFactory(BaseFactory): |
||||||
username = Sequence(lambda n: "user{0}".format(n)) |
"""User factory.""" |
||||||
email = Sequence(lambda n: "user{0}@example.com".format(n)) |
|
||||||
|
username = Sequence(lambda n: 'user{0}'.format(n)) |
||||||
|
email = Sequence(lambda n: 'user{0}@example.com'.format(n)) |
||||||
password = PostGenerationMethodCall('set_password', 'example') |
password = PostGenerationMethodCall('set_password', 'example') |
||||||
active = True |
active = True |
||||||
|
|
||||||
class Meta: |
class Meta: |
||||||
|
"""Factory configuration.""" |
||||||
|
|
||||||
model = User |
model = User |
||||||
|
@ -0,0 +1 @@ |
|||||||
|
"""Main application package.""" |
@ -1,22 +1,23 @@ |
|||||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||||
|
"""Application assets.""" |
||||||
from flask_assets import Bundle, Environment |
from flask_assets import Bundle, Environment |
||||||
|
|
||||||
css = Bundle( |
css = Bundle( |
||||||
"libs/bootstrap/dist/css/bootstrap.css", |
'libs/bootstrap/dist/css/bootstrap.css', |
||||||
"css/style.css", |
'css/style.css', |
||||||
filters="cssmin", |
filters='cssmin', |
||||||
output="public/css/common.css" |
output='public/css/common.css' |
||||||
) |
) |
||||||
|
|
||||||
js = Bundle( |
js = Bundle( |
||||||
"libs/jQuery/dist/jquery.js", |
'libs/jQuery/dist/jquery.js', |
||||||
"libs/bootstrap/dist/js/bootstrap.js", |
'libs/bootstrap/dist/js/bootstrap.js', |
||||||
"js/plugins.js", |
'js/plugins.js', |
||||||
filters='jsmin', |
filters='jsmin', |
||||||
output="public/js/common.js" |
output='public/js/common.js' |
||||||
) |
) |
||||||
|
|
||||||
assets = Environment() |
assets = Environment() |
||||||
|
|
||||||
assets.register("js_all", js) |
assets.register('js_all', js) |
||||||
assets.register("css_all", css) |
assets.register('css_all', css) |
||||||
|
@ -1,22 +1,16 @@ |
|||||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||||
"""Extensions module. Each extension is initialized in the app factory located |
"""Extensions module. Each extension is initialized in the app factory located in app.py.""" |
||||||
in app.py |
|
||||||
""" |
|
||||||
|
|
||||||
from flask_bcrypt import Bcrypt |
from flask_bcrypt import Bcrypt |
||||||
bcrypt = Bcrypt() |
from flask_cache import Cache |
||||||
|
from flask_debugtoolbar import DebugToolbarExtension |
||||||
from flask_login import LoginManager |
from flask_login import LoginManager |
||||||
login_manager = LoginManager() |
from flask_migrate import Migrate |
||||||
|
|
||||||
from flask_sqlalchemy import SQLAlchemy |
from flask_sqlalchemy import SQLAlchemy |
||||||
db = SQLAlchemy() |
|
||||||
|
|
||||||
from flask_migrate import Migrate |
bcrypt = Bcrypt() |
||||||
|
login_manager = LoginManager() |
||||||
|
db = SQLAlchemy() |
||||||
migrate = Migrate() |
migrate = Migrate() |
||||||
|
|
||||||
from flask_cache import Cache |
|
||||||
cache = Cache() |
cache = Cache() |
||||||
|
|
||||||
from flask_debugtoolbar import DebugToolbarExtension |
|
||||||
debug_toolbar = DebugToolbarExtension() |
debug_toolbar = DebugToolbarExtension() |
||||||
|
@ -1,4 +1,3 @@ |
|||||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||||
"""The public module, including the homepage and user auth.""" |
"""The public module, including the homepage and user auth.""" |
||||||
|
from . import views # noqa |
||||||
from . import views |
|
||||||
|
@ -1,63 +1,63 @@ |
|||||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||||
"""Public section, including homepage and signup.""" |
"""Public section, including homepage and signup.""" |
||||||
from flask import (Blueprint, request, render_template, flash, url_for, |
from flask import Blueprint, flash, redirect, render_template, request, url_for |
||||||
redirect, session) |
from flask_login import login_required, login_user, logout_user |
||||||
from flask_login import login_user, login_required, logout_user |
|
||||||
|
|
||||||
from {{cookiecutter.app_name}}.extensions import login_manager |
from {{cookiecutter.app_name}}.extensions import login_manager |
||||||
from {{cookiecutter.app_name}}.user.models import User |
|
||||||
from {{cookiecutter.app_name}}.public.forms import LoginForm |
from {{cookiecutter.app_name}}.public.forms import LoginForm |
||||||
from {{cookiecutter.app_name}}.user.forms import RegisterForm |
from {{cookiecutter.app_name}}.user.forms import RegisterForm |
||||||
|
from {{cookiecutter.app_name}}.user.models import User |
||||||
from {{cookiecutter.app_name}}.utils import flash_errors |
from {{cookiecutter.app_name}}.utils import flash_errors |
||||||
from {{cookiecutter.app_name}}.database import db |
|
||||||
|
|
||||||
blueprint = Blueprint('public', __name__, static_folder="../static") |
blueprint = Blueprint('public', __name__, static_folder='../static') |
||||||
|
|
||||||
|
|
||||||
@login_manager.user_loader |
@login_manager.user_loader |
||||||
def load_user(id): |
def load_user(id): |
||||||
|
"""Load user by ID.""" |
||||||
return User.get_by_id(int(id)) |
return User.get_by_id(int(id)) |
||||||
|
|
||||||
|
|
||||||
@blueprint.route("/", methods=["GET", "POST"]) |
@blueprint.route('/', methods=['GET', 'POST']) |
||||||
def home(): |
def home(): |
||||||
|
"""Home page.""" |
||||||
form = LoginForm(request.form) |
form = LoginForm(request.form) |
||||||
# Handle logging in |
# Handle logging in |
||||||
if request.method == 'POST': |
if request.method == 'POST': |
||||||
if form.validate_on_submit(): |
if form.validate_on_submit(): |
||||||
login_user(form.user) |
login_user(form.user) |
||||||
flash("You are logged in.", 'success') |
flash('You are logged in.', 'success') |
||||||
redirect_url = request.args.get("next") or url_for("user.members") |
redirect_url = request.args.get('next') or url_for('user.members') |
||||||
return redirect(redirect_url) |
return redirect(redirect_url) |
||||||
else: |
else: |
||||||
flash_errors(form) |
flash_errors(form) |
||||||
return render_template("public/home.html", form=form) |
return render_template('public/home.html', form=form) |
||||||
|
|
||||||
|
|
||||||
@blueprint.route('/logout/') |
@blueprint.route('/logout/') |
||||||
@login_required |
@login_required |
||||||
def logout(): |
def logout(): |
||||||
|
"""Logout.""" |
||||||
logout_user() |
logout_user() |
||||||
flash('You are logged out.', 'info') |
flash('You are logged out.', 'info') |
||||||
return redirect(url_for('public.home')) |
return redirect(url_for('public.home')) |
||||||
|
|
||||||
|
|
||||||
@blueprint.route("/register/", methods=['GET', 'POST']) |
@blueprint.route('/register/', methods=['GET', 'POST']) |
||||||
def register(): |
def register(): |
||||||
|
"""Register new user.""" |
||||||
form = RegisterForm(request.form, csrf_enabled=False) |
form = RegisterForm(request.form, csrf_enabled=False) |
||||||
if form.validate_on_submit(): |
if form.validate_on_submit(): |
||||||
new_user = User.create(username=form.username.data, |
User.create(username=form.username.data, email=form.email.data, password=form.password.data, active=True) |
||||||
email=form.email.data, |
flash('Thank you for registering. You can now log in.', 'success') |
||||||
password=form.password.data, |
|
||||||
active=True) |
|
||||||
flash("Thank you for registering. You can now log in.", 'success') |
|
||||||
return redirect(url_for('public.home')) |
return redirect(url_for('public.home')) |
||||||
else: |
else: |
||||||
flash_errors(form) |
flash_errors(form) |
||||||
return render_template('public/register.html', form=form) |
return render_template('public/register.html', form=form) |
||||||
|
|
||||||
|
|
||||||
@blueprint.route("/about/") |
@blueprint.route('/about/') |
||||||
def about(): |
def about(): |
||||||
|
"""About page.""" |
||||||
form = LoginForm(request.form) |
form = LoginForm(request.form) |
||||||
return render_template("public/about.html", form=form) |
return render_template('public/about.html', form=form) |
||||||
|
@ -1,3 +1,3 @@ |
|||||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||||
"""The user module.""" |
"""The user module.""" |
||||||
from . import views |
from . import views # noqa |
||||||
|
@ -1,35 +1,40 @@ |
|||||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||||
|
"""User forms.""" |
||||||
from flask_wtf import Form |
from flask_wtf import Form |
||||||
from wtforms import TextField, PasswordField |
from wtforms import PasswordField, StringField |
||||||
from wtforms.validators import DataRequired, Email, EqualTo, Length |
from wtforms.validators import DataRequired, Email, EqualTo, Length |
||||||
|
|
||||||
from .models import User |
from .models import User |
||||||
|
|
||||||
|
|
||||||
class RegisterForm(Form): |
class RegisterForm(Form): |
||||||
username = TextField('Username', |
"""Register form.""" |
||||||
validators=[DataRequired(), Length(min=3, max=25)]) |
|
||||||
email = TextField('Email', |
username = StringField('Username', |
||||||
validators=[DataRequired(), Email(), Length(min=6, max=40)]) |
validators=[DataRequired(), Length(min=3, max=25)]) |
||||||
|
email = StringField('Email', |
||||||
|
validators=[DataRequired(), Email(), Length(min=6, max=40)]) |
||||||
password = PasswordField('Password', |
password = PasswordField('Password', |
||||||
validators=[DataRequired(), Length(min=6, max=40)]) |
validators=[DataRequired(), Length(min=6, max=40)]) |
||||||
confirm = PasswordField('Verify password', |
confirm = PasswordField('Verify password', |
||||||
[DataRequired(), EqualTo('password', message='Passwords must match')]) |
[DataRequired(), EqualTo('password', message='Passwords must match')]) |
||||||
|
|
||||||
def __init__(self, *args, **kwargs): |
def __init__(self, *args, **kwargs): |
||||||
|
"""Create instance.""" |
||||||
super(RegisterForm, self).__init__(*args, **kwargs) |
super(RegisterForm, self).__init__(*args, **kwargs) |
||||||
self.user = None |
self.user = None |
||||||
|
|
||||||
def validate(self): |
def validate(self): |
||||||
|
"""Validate the form.""" |
||||||
initial_validation = super(RegisterForm, self).validate() |
initial_validation = super(RegisterForm, self).validate() |
||||||
if not initial_validation: |
if not initial_validation: |
||||||
return False |
return False |
||||||
user = User.query.filter_by(username=self.username.data).first() |
user = User.query.filter_by(username=self.username.data).first() |
||||||
if user: |
if user: |
||||||
self.username.errors.append("Username already registered") |
self.username.errors.append('Username already registered') |
||||||
return False |
return False |
||||||
user = User.query.filter_by(email=self.email.data).first() |
user = User.query.filter_by(email=self.email.data).first() |
||||||
if user: |
if user: |
||||||
self.email.errors.append("Email already registered") |
self.email.errors.append('Email already registered') |
||||||
return False |
return False |
||||||
return True |
return True |
||||||
|
@ -1,12 +1,13 @@ |
|||||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||||
|
"""User views.""" |
||||||
from flask import Blueprint, render_template |
from flask import Blueprint, render_template |
||||||
from flask_login import login_required |
from flask_login import login_required |
||||||
|
|
||||||
blueprint = Blueprint("user", __name__, url_prefix='/users', |
blueprint = Blueprint('user', __name__, url_prefix='/users', static_folder='../static') |
||||||
static_folder="../static") |
|
||||||
|
|
||||||
|
|
||||||
@blueprint.route("/") |
@blueprint.route('/') |
||||||
@login_required |
@login_required |
||||||
def members(): |
def members(): |
||||||
return render_template("users/members.html") |
"""List members.""" |
||||||
|
return render_template('users/members.html') |
||||||
|
Loading…
Reference in new issue