This time, we will add a new user registration function.
Create a model for User, just as you created a Review model last time.
python:./cafesite/models/users.py
from cafe_site import db
from datetime import datetime
import bcrypt
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50))
password = db.Column(db.String(50))
salt = db.Column(db.String(50))
created_at = db.Column(db.DateTime)
def __init__(self, username=None, password=None):
self.username = username
self.salt = bcrypt.gensalt().decode()
self.password = bcrypt.hashpw(password.encode(), self.salt.encode()).decode()
self.created_at = datetime.utcnow()
def __repr__(self):
return '<Entry id:{} username:{}>'.format(self.id, self.username)
Since it is not good for security to save the password as it is in the database, the password is encrypted and saved in the database.
bcrypt
In ** users.py **, generate salt with self.salt = bcrypt.gensalt (). Decode ()
,
Security is enhanced by combining the password hashed with self.password = bcrypt.hashpw (password.encode (), self.salt.encode ()). Decode ()
with the generated salt. I will.
Add a process to models / reviews.py to determine which user wrote the article.
python:./cafesite/models/reviews.py
from cafe_site import db
from datetime import datetime
class Review(db.Model):
from cafe_site.models.users import User
__tablename__ = 'Reviews'
id = db.Column(db.Integer, primary_key=True)
star = db.Column(db.Integer)
title = db.Column(db.String(50), unique=True)
text = db.Column(db.Text)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
user = db.relationship('User', foreign_keys=user_id)
created_at = db.Column(db.DateTime)
def __init__(self, star=None, title=None, text=None, user_id=None):
self.star = star
self.title = title
self.text = text
self.user_id = user_id
self.created_at = datetime.utcnow()
def __repr__(self):
return '<Review id:{} star:{} title:{} text:{} user_id:{}>'.format(self.id, self.star, self.title, self.text, self.user_id)
Receive the id attribute generated by the User model as a foreign key with ʻuser_id = db.Column (db.Integer, db.ForeignKey ('users.id'))and ʻuser = db.relationship ('User', foreign_keys) = user_id)
is processed so that the Review model can be operated using a foreign key.
Edit theme.html and add a "Sign up" link for new registration in the navigation bar.
html:./cafe_site/templates/theme.html
<ul class="main-nav">
{% if not session.logged_in %}
<li><a href="{{ url_for('user.new_user') }}">Signup</a></li>
{% else %}
{% endif %}
</ul>
python:./cafesite/views/users.py
@user.route('/users/new', methods=['GET'])
def new_user():
return render_template('users/new.html', id='user')
html:./cafe_site/templates/users/new.html
{% extends "theme.html" %}
{% block title %}Coffee House{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<div class="wrapper">
<h2 class="page-title">Signup</h2>
</div>
<div class="login-content wrapper">
<form action="{{ url_for('user.add_user') }}" method=post>
<div>
<label for="name">User name</label>
<input placeholder="username" type="text" name=username>
</div>
<div>
<label for="Password">password</label>
<input placeholder="password" type="password" name=password>
</div>
<input type="submit" class="button" value="sign up">
</form>
</div>
{% endblock %}
{% block footer %}
<footer>
<div class="wrapper">
<p><small>© Coffee House</small></p>
</div>
</footer>
{% endblock %}
This completes the creation of the new registration form. Next, create a function to save the registered user data in the database using the model instance created earlier.
In users / new.html, the post destination of the form is ʻAction =" {{url_for ('user.add_user')}} "`. Create ** user.add_user ** and add a process to receive the posted content and save it in the database. Add ** add_user ** to views / users.py.
python:./cafesite/views/users.py
@user.route('/users', methods=['POST'])
def add_user():
user = User(
username=request.form['username'],
password=request.form['password']
)
db.session.add(user)
db.session.commit()
flash('New user registration is complete. Please login.')
return redirect(url_for('loging.login'))
Use the User model to create a model instance for the username and password sent to you and store it in the database. Now let's take a look at the big picture of views / users.py.
python:./cafesite/views/users.py
from flask import request, redirect, url_for, render_template, flash, session
from cafe_site import app
from cafe_site import db
from cafe_site.models.users import User
from cafe_site.views.loging import login_required
from flask import Blueprint
user = Blueprint('user', __name__)
@user.route('/users', methods=['POST'])
def add_user():
user = User(
username=request.form['username'],
password=request.form['password']
)
db.session.add(user)
db.session.commit()
flash('New user registration is complete. Please login.')
return redirect(url_for('loging.login'))
@user.route('/users/new', methods=['GET'])
def new_user():
return render_template('users/new.html', id='user')
python:./cafesite/views/loging.py
from flask import request, redirect, url_for, render_template, flash, session
from cafe_site import app
from functools import wraps
from cafe_site.models.users import User
import bcrypt
from flask import Blueprint
loging = Blueprint('loging', __name__)
def login_required(loging):
@wraps(loging)
def inner(*args, **kwargs):
if not session.get('logged_in'):
return redirect(url_for('loging.login'))
return loging(*args, **kwargs)
return inner
@loging.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
try:
user = User.query.filter_by(username=request.form['username']).first()
except:
flash('The user name is different')
return render_template('login.html')
if request.form['username'] != user.username:
flash('The user name is different')
elif bcrypt.hashpw(request.form['password'].encode(), user.salt.encode()).decode() != user.password:
flash('Password is different')
else:
session['logged_in'] = True
session['user_id'] = user.id
flash('You are now logged')
return redirect(url_for('review.show_reviews'))
return render_template('login.html', id="login")
@loging.route('/logout')
def logout():
session.pop('logged_in', None)
flash('logged out')
return redirect(url_for('review.show_reviews'))
@loging.app_errorhandler(404)
def non_existant_route(error):
return redirect(url_for('loging.login'))
Reprocessed so that you can log in with the user data sent from the User model.
Finally, make changes to cafe_site / __ init__.py.
python:./cafe_site/__init__.py
from cafe_site.views.users import user
app.register_blueprint(user)
The web application is now complete.
Next time, I will explain how to launch the web application created this time on the cloud using heroku.
Recommended Posts