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_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
from flask_login import LoginManager from flask_login import LoginManager
from flask_mail import Mail
import os
app = Flask(__name__) app = Flask(__name__)
app.config['SECRET_KEY'] = '57636aef33666affr6' app.config['SECRET_KEY'] = '5791628bb0b13ce0c676dfde280ba245'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app) db = SQLAlchemy(app)
bcrypt = Bcrypt(app) bcrypt = Bcrypt(app)
@ -12,4 +14,12 @@ login_manager = LoginManager(app)
login_manager.login_view = 'login' login_manager.login_view = 'login'
login_manager.login_message_category = 'info' 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 from minibase import route

@ -6,10 +6,14 @@ from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationE
from minibase.models import User from minibase.models import User
class registrationForm(FlaskForm): class registrationForm(FlaskForm):
username = StringField('User Name', validators=[DataRequired(),Length(min = 3, max = 20)]) username = StringField('User Name',
email = StringField('Email', validators=[DataRequired(),Email()]) validators=[DataRequired(),Length(min = 3, max = 20)])
password = PasswordField('Password', validators=[DataRequired()]) email = StringField('Email',
password_confirm = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')]) validators=[DataRequired(),Email()])
password = PasswordField('Password',
validators=[DataRequired()])
password_confirm = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Sing Up') submit = SubmitField('Sing Up')
def validate_username(self, username): def validate_username(self, username):
@ -23,14 +27,16 @@ class registrationForm(FlaskForm):
raise ValidationError('That email is taken do you have an acocunt ?') raise ValidationError('That email is taken do you have an acocunt ?')
class loginForm(FlaskForm): class loginForm(FlaskForm):
email = StringField('Email',validators=[DataRequired(),Email()]) email = StringField('Email',
password = PasswordField('Password',validators=[DataRequired()]) validators=[DataRequired(),Email()])
password = PasswordField('Password',
validators=[DataRequired()])
remember = BooleanField('Remember Me') remember = BooleanField('Remember Me')
submit = SubmitField('Log In') submit = SubmitField('Log In')
class updateAccountForm(FlaskForm): class updateAccountForm(FlaskForm):
username = StringField('User Name', username = StringField('User Name',
validators=[DataRequired(),Length(min = 3, max = 20)]) validators=[DataRequired(),Length(min = 3, max = 20)])
email = StringField('Email', email = StringField('Email',
validators=[DataRequired(),Email()]) validators=[DataRequired(),Email()])
picture = FileField('Update Profile Picture', picture = FileField('Update Profile Picture',
@ -50,6 +56,26 @@ class updateAccountForm(FlaskForm):
raise ValidationError('That email is taken do you have an acocunt ?') raise ValidationError('That email is taken do you have an acocunt ?')
class postForm(FlaskForm): class postForm(FlaskForm):
title = StringField('Title', validators=[DataRequired(),Length(min = 3, max = 100)]) title = StringField('Title',
content = TextAreaField('Content', validators=[DataRequired()]) validators=[DataRequired(),Length(min = 3, max = 100)])
content = TextAreaField('Content',
validators=[DataRequired()])
submit = SubmitField('Post') 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 datetime import datetime
from minibase import db, login_manager from minibase import db, login_manager, app
from flask_login import UserMixin from flask_login import UserMixin
@login_manager.user_loader @login_manager.user_loader
def load_user(user_id): def load_user(user_id):
return User.query.get(int(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) password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True) 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): def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.image_file}')" return f"User('{self.username}', '{self.email}', '{self.image_file}')"
@ -26,3 +41,4 @@ class Post(db.Model):
def __repr__(self): def __repr__(self):
return f"User('{self.title}', '{self.date_posted}')" return f"User('{self.title}', '{self.date_posted}')"

@ -2,11 +2,11 @@ import os
import secrets import secrets
from PIL import Image from PIL import Image
from flask import render_template, url_for, flash, redirect, request, abort from flask import render_template, url_for, flash, redirect, request, abort
from minibase import app, db, bcrypt from minibase import app, db, bcrypt, mail
from minibase.forms import registrationForm, loginForm, updateAccountForm, postForm from minibase.forms import registrationForm, loginForm, updateAccountForm, postForm, requestResetForm, resetPasswordForm
from minibase.models import User, Post from minibase.models import User, Post
from flask_login import login_user, current_user, logout_user, login_required 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 / #Redirect from / and also /home routes to the /
@app.route("/") @app.route("/")
@ -33,7 +33,7 @@ def register():
db.session.add(user) db.session.add(user)
db.session.commit() db.session.commit()
flash(f'Your account has benn created you can now log in!','success') 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) return render_template('register.html', title='Register', form=form)
@ -141,3 +141,43 @@ def user_posts(username):
.order_by(Post.date_posted.asc())\ .order_by(Post.date_posted.asc())\
.paginate(page=page, per_page=2) .paginate(page=page, per_page=2)
return render_template('user_posts.html', posts=posts, user=user) 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") }} {{ form.submit(class="btn btn-outline-info") }}
</div> </div>
<small class="text-muted ml-2"> <small class="text-muted ml-2">
<a href="#">Forgot Password?</a> <a href="{{ url_for('reset_request') }}">Forgot Password?</a>
</small> </small>
</form> </form>
</div> </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