Flask is very good and will be the definitiv solution for the database intrerface

master
key 2 years ago
parent d348025865
commit 23aa5d8cee

@ -2,9 +2,11 @@ from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_mail import Mail
import os
app = Flask(__name__)
app.config['SECRET_KEY'] = '57636aef33666affr6'
app.config['SECRET_KEY'] = '5791628bb0b13ce0c676dfde280ba245'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
@ -12,4 +14,12 @@ login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
app.config['MAIL_SERVER']= 'smtp.googlemail.com'
app.config['MAIL_PORT']= 465
app.config['MAIL_USE_TLS']= False
app.config['MAIL_USE_SSL']= True
app.config['MAIL_USERNAME']= 'kerem.yollu@gmail.com'
app.config['MAIL_PASSWORD']= 'eoilsjxjwmnfjbbj'
mail = Mail(app)
from minibase import route

@ -6,10 +6,14 @@ from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationE
from minibase.models import User
class registrationForm(FlaskForm):
username = StringField('User Name', validators=[DataRequired(),Length(min = 3, max = 20)])
email = StringField('Email', validators=[DataRequired(),Email()])
password = PasswordField('Password', validators=[DataRequired()])
password_confirm = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
username = StringField('User Name',
validators=[DataRequired(),Length(min = 3, max = 20)])
email = StringField('Email',
validators=[DataRequired(),Email()])
password = PasswordField('Password',
validators=[DataRequired()])
password_confirm = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Sing Up')
def validate_username(self, username):
@ -23,14 +27,16 @@ class registrationForm(FlaskForm):
raise ValidationError('That email is taken do you have an acocunt ?')
class loginForm(FlaskForm):
email = StringField('Email',validators=[DataRequired(),Email()])
password = PasswordField('Password',validators=[DataRequired()])
email = StringField('Email',
validators=[DataRequired(),Email()])
password = PasswordField('Password',
validators=[DataRequired()])
remember = BooleanField('Remember Me')
submit = SubmitField('Log In')
class updateAccountForm(FlaskForm):
username = StringField('User Name',
validators=[DataRequired(),Length(min = 3, max = 20)])
validators=[DataRequired(),Length(min = 3, max = 20)])
email = StringField('Email',
validators=[DataRequired(),Email()])
picture = FileField('Update Profile Picture',
@ -50,6 +56,26 @@ class updateAccountForm(FlaskForm):
raise ValidationError('That email is taken do you have an acocunt ?')
class postForm(FlaskForm):
title = StringField('Title', validators=[DataRequired(),Length(min = 3, max = 100)])
content = TextAreaField('Content', validators=[DataRequired()])
title = StringField('Title',
validators=[DataRequired(),Length(min = 3, max = 100)])
content = TextAreaField('Content',
validators=[DataRequired()])
submit = SubmitField('Post')
class requestResetForm(FlaskForm):
email = StringField('Email',
validators=[DataRequired(),Email()])
submit = SubmitField('Request Password Reset')
def validate_email(self, email):
email = User.query.filter_by(email=email.data).first()
if email is None:
raise ValidationError('There is no Account with this email your must register first.')
class resetPasswordForm(FlaskForm):
password = PasswordField('Password',
validators=[DataRequired()])
password_confirm = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Reset Password')

@ -1,7 +1,9 @@
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from datetime import datetime
from minibase import db, login_manager
from minibase import db, login_manager, app
from flask_login import UserMixin
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
@ -14,6 +16,19 @@ class User(db.Model, UserMixin):
password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
def get_reset_token(self, expires_sec=1800):
s = Serializer(app.config['SECRET_KEY'], expires_sec)
return s.dumps({'user_id': self.id}).decode('utf-8')
@staticmethod
def verify_reset_token(token):
s = Serializer(app.config['SECRET_KEY'])
try:
user_id = s.loads(token)['user_id']
except:
return none
return User.query.get(user_id)
def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.image_file}')"
@ -26,3 +41,4 @@ class Post(db.Model):
def __repr__(self):
return f"User('{self.title}', '{self.date_posted}')"

@ -2,11 +2,11 @@ import os
import secrets
from PIL import Image
from flask import render_template, url_for, flash, redirect, request, abort
from minibase import app, db, bcrypt
from minibase.forms import registrationForm, loginForm, updateAccountForm, postForm
from minibase import app, db, bcrypt, mail
from minibase.forms import registrationForm, loginForm, updateAccountForm, postForm, requestResetForm, resetPasswordForm
from minibase.models import User, Post
from flask_login import login_user, current_user, logout_user, login_required
from flask_mail import Message
#Redirect from / and also /home routes to the /
@app.route("/")
@ -33,7 +33,7 @@ def register():
db.session.add(user)
db.session.commit()
flash(f'Your account has benn created you can now log in!','success')
return redirect(url_for('home'))
return redirect(url_for('login'))
return render_template('register.html', title='Register', form=form)
@ -141,3 +141,43 @@ def user_posts(username):
.order_by(Post.date_posted.asc())\
.paginate(page=page, per_page=2)
return render_template('user_posts.html', posts=posts, user=user)
def send_reset_email(user):
token = user.get_reset_token()
msg = Message('Password Reset Request',
sender='noreply@demo.com',
recipients=[user.email])
msg.body = f'''To reset your password, visit the following link:
{url_for('reset_token', token=token, _external=True)}
If you didn't make this request, then simply ingnore this email and no chancges will be made.
'''
mail.send(msg)
@app.route("/reset_password", methods=['GET', 'POST'])
def reset_request():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = requestResetForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
send_reset_email(user)
flash('An Email has benn sent with instruction to reset your password', 'warning')
return render_template('reset_request.html', title='Reset Password', form=form)
@app.route("/reset_password/<token>", methods=['GET', 'POST'])
def reset_token(token):
if current_user.is_authenticated:
return redirect(url_for('home'))
user = User.verify_reset_token(token)
if user is None:
flash('That is an invalid or expired token', 'warning')
return redirect(url_for('reset_request'))
form = resetPasswordForm()
if form.validate_on_submit():
hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user.password = hashed_pw
db.session.commit()
flash(f'Your password has benn udated','success')
return redirect(url_for('login'))
return render_template('reset_token.html', title='Reset Password', form=form)

Binary file not shown.

@ -40,7 +40,7 @@
{{ form.submit(class="btn btn-outline-info") }}
</div>
<small class="text-muted ml-2">
<a href="#">Forgot Password?</a>
<a href="{{ url_for('reset_request') }}">Forgot Password?</a>
</small>
</form>
</div>

@ -0,0 +1,27 @@
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Reset Password</legend>
<div class="form-group">
{{ form.email.label(class="form-control-label") }}
{% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email(class="form-control form-control-lg") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}

@ -0,0 +1,40 @@
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Reset Password</legend>
<div class="form-group">
{{ form.password.label(class="form-control-label") }}
{% if form.password.errors %}
{{ form.password(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.password_confirm.label(class="form-control-label") }}
{% if form.password_confirm.errors %}
{{ form.password_confirm(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.password_confirm.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password_confirm(class="form-control form-control-lg") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}
Loading…
Cancel
Save