I am working on a simple CRUD app as a personal project using Flask. I am currently working on the user service and I just finished the registration process. I am also trying to use as less as libraries as I could, this is why you won't see any ORM or Flask-wtf (for learning purposes).
models.py: contains 1 class -
User
. TheUser
class is just a representation of aUser
object, there is no method present in this class expect a__str__
method.services.py: contains 1 class -
UserService
. No constructor or class variables. TheUserService
is use to interact with theUser
such as create a new user, update a user parameter or delete a user. Most of theUserService
methods takes aUser
as a parameter expect the method to create a newUser
,add_user()
repo.py: contains 1 class -
UserRepository
. As I am not using any ORM, I needed a way to interact with the database to add, delete or update rows in theUser
table. I could have directly make the queries on theUser
service, but I think I will actually broke the separation of concerns;Route.py: Once the user fill the
register.html
registration form, the form is sent to the/new-user
route.
I am wondering about multiple things:
I read that commit to the repository using sqlite take a decent amount of resources. I do have a save method on my UserRepository class that just do a conn.commit(). But do I have to call this method each time I am creating a new user or like it should be call like after creating x new
Users
or x new db-operations?I am converting my
active
variable fromBoolean
toInteger
(1 or 0) because this is how it is set in myUser
table on mySQL db astinyint(1) DEFAULT '1'
. Should I also use 1/0 on my code or keep it as True/False and convert fromBoolean
toInteger
in myUserRepository
class?If you have any other red flag or design issues that I should not do, let me know :)
Code bellow:
user/routes.py
user = Blueprint('user', __name__, template_folder='templates')
@user.route('/register')
def login():
return render_template('register.html')
# register new user
@user.route('/new-user',methods = ['POST'])
def register_user():
# gather form data
form_email = request.form.get('email')
form_password = request.form.get('psw')
# register_user() will return a User object
new_user = UserService().register_user(form_email, form_password)
user_repository = UserRepository(conn, 'users')
user_repository.add_user(new_user)
user_repository.save()
# will probably change the return and add try-catch?
return "ok"
models.py (User class)
class User():
def __init__(self, email, password, registration_date,
active, sign_in_count, current_sign_in_on, last_sign_in_on):
self.email = email
self.password = password
self.registration_date = registration_date
self.active = active
# Activity tracking
self.sign_in_count = sign_in_count
self.current_sign_in_on = current_sign_in_on
self.last_sign_in_on = last_sign_in_on
def __str__(self):
user_attributes = vars(self)
return (', '.join("%s: %s" % item for item in user_attributes.items()))
services.py (UserService class)
class UserService():
def register_user(self,
email,
password):
# sign-in count is 1 since it is a new user
sign_in_count = 1
# today dates for registration date, current sign-in date and last sign-in date since it's a new user
today_date = datetime.today().strftime('%Y-%m-%d')
active = True
new_user = User(email, password, today_date, active,
sign_in_count, today_date, today_date)
return new_user
def desactivate_user(self, User):
if User.active == False:
print(f"User {User.email} is already inactive")
User.active = False
def reactive_user(self, User):
if User.active == True:
print(f"User {User.email} is already active")
User.active = True
def is_active(self, User):
return User.is_active
def update_activity_tracking(self, User, ip_address):
User.sign_in_count += 1
User.last_sign_in_on = User.current_sign_in_on
User.current_sign_in_on = datetime.datetime.now()
def update_password(self, User, new_password):
User.password = get_hashed_password(new_password)
repo.py (UserRepository class)
class UserRepository():
def __init__(self, conn, table):
self.conn = conn
self.table = table
def add_user(self, User):
sql = "INSERT INTO users (email, password, is_active, sign_in_count, current_sign_in_on, last_sign_in_on) VALUES (%s, %s, %s, %s, %s, %s)"
cursor = self.conn.cursor()
# the is_active column in the DB is a tinyint(1). True = 1 and False = 0
if User.active == True:
is_active = 1
is_active = 0
cursor.execute(sql, ( User.email, User.password, is_active, User.sign_in_count, User.current_sign_in_on, User.last_sign_in_on))
resp = cursor.fetchall()
return resp
def delete_user(self):
return ""
def get_user(self):
return ""
def save(self):
self.conn.commit()