Skip to main content

User Management System with Python, Flask and MySQL

In our previous Python tutorial, we have to develop Weather App in Python using Flask. In this tutorial, we will explain how to develop User Management System with Python, Flask and MySQL.

User section is an important part of any web application in which users are created, updated, deleted, viewed etc. We can easily develop user managment system in Python using Flask and MySQL packages.

So let’s proceed to develop User Management System with Python, Flask and MySQL.

Application Setup

We will create application directory user-management-system-python using below command.

$ mkdir user-management-system-python

then moved within project direcotry

$ cd user-management-system-python

Modules Required

We will use folloing modules in this application from Python.

  • Flask: It is a micro framework from Python to create web application. So we will install this module to create web applications. We will install it using the below command:
  • pip install Flask
    
  • flask_mysqldb: This is Python package that can be used to connect to MySQL database. We will install it using the below command:
  • pip install flask_mysqldb
    

Create MySQL Database and Table

We will create MySQL database user-system and create tableuser to store users details.

CREATE TABLE `user` (
  `userid` int(11) NOT NULL,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  `password` varchar(255) NOT NULL,
  `role` enum('admin','user') NOT NULL,
  `country` varchar(350) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE `user`
  ADD PRIMARY KEY (`userid`);
  
ALTER TABLE `user`
  MODIFY `userid` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;

Create Application File

We will create application file app.py into project root directory.

Then we will import installed module Flask and flask_mysqldb with it’s helpers.

we will create Flask app and assign app.config vaues for MySQL database connection to access database.

from flask import Flask, render_template, request, redirect, url_for, session
from flask_mysqldb import MySQL
import MySQLdb.cursors
import re  

app = Flask(__name__) 

app.secret_key = 'xyzsdfg'
  
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = ''
app.config['MYSQL_DB'] = 'user-system'
  
mysql = MySQL(app)  

@app.route('/')


if __name__ == "__main__":
    app.run()

Implement User Login Section

We will create template file templates/login.html and create FORM with input and submit button.

<form action="{{ url_for('login') }}" method="post">
	{% if mesage is defined and mesage %}
		<div class="alert alert-warning">{{ mesage }}</div>
	{% endif %}
	<div class="form-group">
		<label for="email">Email:</label>
		<input type="email" class="form-control" id="email" name="email" placeholder="Enter email" name="email">
	</div>
	<div class="form-group">
		<label for="pwd">Password:</label>
		<input type="password" class="form-control" id="password" name="password" placeholder="Enter password" name="pswd">
	</div>    
	<button type="submit" class="btn btn-primary">Login</button>		
</form>

Then we will create function login() in app.py file and call function render_template() to render login.html file to load user login page. We will implement login functionality by executing SQL query to perform user login.

@app.route('/login', methods =['GET', 'POST'])
def login():
    mesage = ''
    if request.method == 'POST' and 'email' in request.form and 'password' in request.form:
        email = request.form['email']
        password = request.form['password']
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute('SELECT * FROM user WHERE email = % s AND password = % s', (email, password, ))
        user = cursor.fetchone()
        if user:            
            if user['role'] == 'admin':
                session['loggedin'] = True
                session['userid'] = user['userid']
                session['name'] = user['name']
                session['email'] = user['email']
                mesage = 'Logged in successfully !'
                return redirect(url_for('users'))
            else:
               mesage = 'Only admin can login' 
        else:
            mesage = 'Please enter correct email / password !'
    return render_template('login.html', mesage = mesage)
  
@app.route('/logout')

Implement Add New User

We will create template file templates/register.html and create user FORM with input and submit button.

<form action="{{ url_for('register') }}" method="post">
	{% if mesage is defined and mesage %}
		<div class="alert alert-warning">{{ mesage }}</div>
	{% endif %}
	<div class="form-group">
		<label for="name">Name:</label>
		<input type="text" class="form-control" id="name" name="name" placeholder="Enter name">
	</div>
	<div class="form-group">
		<label for="email">Email:</label>
		<input type="email" class="form-control" id="email" name="email" placeholder="Enter email">
	</div>
	<div class="form-group">
		<label for="pwd">Password:</label>
		<input type="password" class="form-control" id="password" name="password" placeholder="Enter password">
	</div>  
	<div class="form-group">
		<label for="role">Role:</label>
		<select class="form-control" id="role" name="role">
			<option value="admin">Admin</option>
			<option value="user">User</option>			
		</select>
	</div>
	<div class="form-group">
		<label for="country">Country:</label>
		<input type="text" class="form-control" id="country" name="country">
	</div>
	<button type="submit" class="btn btn-primary">Register</button>		
</form>

We will implement new user add using form submit post values. We will insert users details into user table.

@app.route('/register', methods =['GET', 'POST'])
def register():
    mesage = ''
    if request.method == 'POST' and 'name' in request.form and 'password' in request.form and 'email' in request.form :
        userName = request.form['name']
        password = request.form['password']
        email = request.form['email']
        role = request.form['role']
        country = request.form['country']
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute('SELECT * FROM user WHERE email = % s', (email, ))
        account = cursor.fetchone()
        if account:
            mesage = 'User already exists !'
        elif not re.match(r'[^@]+@[^@]+\.[^@]+', email):
            mesage = 'Invalid email address !'
        elif not userName or not password or not email:
            mesage = 'Please fill out the form !'
        else:
            cursor.execute('INSERT INTO user VALUES (NULL, % s, % s, % s, % s, % s)', (userName, email, password, role, country))
            mysql.connection.commit()
            mesage = 'New user created!'
    elif request.method == 'POST':
        mesage = 'Please fill out the form !'
    return render_template('register.html', mesage = mesage)

Implement User Listing

We will create templates/users.html template file and create HTML to display user list. Then implement to loop through user data and display list with details.

<table class="table table-striped">
    <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Role</th>
		<th>Country</th>
		<th></th>
		<th></th>
		<th></th>
		<th></th>
      </tr>
    </thead>
    <tbody>
	  {% for user in users %}
      <tr>
        <td>{{user.name}}</td>
        <td>{{user.email}}</td>
        <td>{{user.role}}</td>
		<td>{{user.country}}</td>
		<td><a href="{{url_for('view', userid=user.userid)}}" class="btn btn-success">View</a></td>
		<td><a href="{{url_for('edit', userid=user.userid)}}" class="btn btn-primary">Edit</a></td>
		<td><a href="{{url_for('password_change', userid=user.userid)}}" class="btn btn-warning">Change Password</a></td>
		<td><a href="{{url_for('delete', userid=user.userid)}}" class="btn btn-danger">Delete</a></td>
      </tr> 
	{% endfor %}	  
    </tbody>
</table>	

We will create function users() in app.py and implement functionality to get all users data from database table and pass to template users.html to display list.

@app.route("/users", methods =['GET', 'POST'])
def users():
    if 'loggedin' in session:
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute('SELECT * FROM user')
        users = cursor.fetchall()    
        return render_template("users.html", users = users)
    return redirect(url_for('login'))
    

Implement User Edit Section

We will create template file templates/edit.html and create user edit form.

<form action="{{ url_for('edit') }}" method="post">
	{% if mesage is defined and mesage %}
		<div class="alert alert-warning">{{ mesage }}</div>
	{% endif %}
	<div class="form-group">
		<label for="name">Name:</label>
		<input type="text" class="form-control" id="name" name="name" value="{{ editUser.name }}">
	</div>
	<div class="form-group">
		<label for="role">Role:</label>
		<select class="form-control" id="role" name="role">
			<option value="admin" {% if editUser.role == 'admin' %}selected{% endif %}>Admin</option>
			<option value="user"  {% if editUser.role == 'user' %}selected{% endif %}>User</option>			
		</select>
	</div>
	<div class="form-group">
		<label for="country">Country:</label>
		<input type="text" class="form-control" id="country" name="country" value="{{ editUser.country }}">
	</div>
		
	<input type="hidden" id="userid" name="userid" value="{{ editUser.userid }}">
	<button type="submit" class="btn btn-primary">Save</button>		
</form>

We will create edit() function in app.py and implement user edit functionality and render edit.html template.

@app.route("/edit", methods =['GET', 'POST'])
def edit():
    msg = ''    
    if 'loggedin' in session:
        editUserId = request.args.get('userid')
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute('SELECT * FROM user WHERE userid = % s', (editUserId, ))
        editUser = cursor.fetchone()
        if request.method == 'POST' and 'name' in request.form and 'userid' in request.form and 'role' in request.form and 'country' in request.form :
            userName = request.form['name']   
            role = request.form['role']
            country = request.form['country']            
            userId = request.form['userid']
            if not re.match(r'[A-Za-z0-9]+', userName):
                msg = 'name must contain only characters and numbers !'
            else:
                cursor.execute('UPDATE user SET  name =% s, role =% s, country =% s WHERE userid =% s', (userName, role, country, (userId, ), ))
                mysql.connection.commit()
                msg = 'User updated !'
                return redirect(url_for('users'))
        elif request.method == 'POST':
            msg = 'Please fill out the form !'        
        return render_template("edit.html", msg = msg, editUser = editUser)
    return redirect(url_for('login'))

Implement User Password Change

We will create template file templates/password_change.html and create password change form to implement functionality.

<form action="{{ url_for('password_change') }}" method="post">
	{% if mesage is defined and mesage %}
		<div class="alert alert-warning">{{ mesage }}</div>
	{% endif %}		
	<div class="form-group">
		<label for="country">Password:</label>
		<input type="password" class="form-control" id="password" name="password">
	</div>
	<div class="form-group">
		<label for="country">Confirm Password:</label>
		<input type="password" class="form-control" id="confirm_pass" name="confirm_pass">
	</div>
	<input type="hidden" id="userid" name="userid" value="{{ changePassUserId }}">
	<button type="submit" class="btn btn-primary">Update</button>		
</form>

We will create a function password_change() in app.py and implement user password change functionality.

@app.route("/password_change", methods =['GET', 'POST'])
def password_change():
    mesage = ''
    if 'loggedin' in session:
        changePassUserId = request.args.get('userid')        
        if request.method == 'POST' and 'password' in request.form and 'confirm_pass' in request.form and 'userid' in request.form  :
            password = request.form['password']   
            confirm_pass = request.form['confirm_pass'] 
            userId = request.form['userid']
            if not password or not confirm_pass:
                mesage = 'Please fill out the form !'
            elif password != confirm_pass:
                mesage = 'Confirm password is not equal!'
            else:
                cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
                cursor.execute('UPDATE user SET  password =% s WHERE userid =% s', (password, (userId, ), ))
                mysql.connection.commit()
                mesage = 'Password updated !'            
        elif request.method == 'POST':
            mesage = 'Please fill out the form !'        
        return render_template("password_change.html", mesage = mesage, changePassUserId = changePassUserId)
    return redirect(url_for('login'))

Implement View User Details

We will create templates/view.html file and implement to display user details.

<h3>User Details</h3> 
<br>
<h4>{{user.name}}</h4>
<p><strong>Email: </strong> {{user.email}}. </p>
<p><strong>Role: </strong> {{user.role}} </p>
<p><strong>Skills: </strong> {{user.country}}</p>

We will create function view() in app.py and implement to get user details from database table and pass to template view.html to display user details.

@app.route("/view", methods =['GET', 'POST'])
def view():
    if 'loggedin' in session:
        viewUserId = request.args.get('userid')   
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute('SELECT * FROM user WHERE userid = % s', (viewUserId, ))
        user = cursor.fetchone()   
        return render_template("view.html", user = user)
    return redirect(url_for('login'))

You can download the complete source code of project from the Download link below.
Download