0% found this document useful (0 votes)
16 views

Document (17)

Hahahsvsvsjalxhdhslks
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Document (17)

Hahahsvsvsjalxhdhslks
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

To create a simple task and project management tool using Python, we will use the

Flask framework for building the web application. This guide will walk you through
the setup and development of the app step by step, using Flask to handle the back-
end and simple HTML for the front-end. Additionally, we will use SQLite as the
database to store tasks and projects.

Step 1: Install Dependencies

First, make sure you have Python installed. You'll also need to install Flask and other
dependencies.

pip install flask flask_sqlalchemy flask_wtf

Step 2: Folder Structure

Create the following folder structure in your Visual Studio Code project.

task_management_tool/

├── app/
│ ├── __init__.py
│ ├── routes.py
│ ├── models.py
│ ├── forms.py
│ └── __init__.py
├── templates/
│ ├── base.html
│ ├── login.html
│ ├── dashboard.html
│ └── task.html
├── static/
│ └── style.css
├── config.py
└── run.py

Step 3: Create the Main Files


1. run.py - Entry Point to the Application

This file is where the Flask app is run.

from app import create_app

app = create_app()

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

2. config.py - Configuration Settings

Set up your configuration for the database and other settings.

import os

class Config:
SECRET_KEY = os.urandom(24)
SQLALCHEMY_DATABASE_URI = 'sqlite:///tasks.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False

3. app/__init__.py - Initialize the Flask App

This file initializes the Flask app and binds the database.

from flask import Flask


from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect

db = SQLAlchemy()
csrf = CSRFProtect()

def create_app():
app = Flask(__name__)
app.config.from_object('config.Config')

db.init_app(app)
csrf.init_app(app)

from app.routes import main_bp


app.register_blueprint(main_bp)

return app
4. app/models.py - Database Models

This file will contain your Project and Task models.

from datetime import datetime


from app import db

class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
tasks = db.relationship('Task', backref='project', lazy=True)

class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
description = db.Column(db.String(200), nullable=True)
deadline = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
completed = db.Column(db.Boolean, default=False)
project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False)
5. app/forms.py - Forms for Handling User Input

Here, we define forms for task creation and login.

from flask_wtf import FlaskForm


from wtforms import StringField, BooleanField, SubmitField, DateTimeField
from wtforms.validators import DataRequired

class TaskForm(FlaskForm):
title = StringField('Title', validators=[DataRequired()])
description = StringField('Description')
deadline = DateTimeField('Deadline', format='%Y-%m-%d %H:%M:%S')
completed = BooleanField('Completed')
submit = SubmitField('Save Task')
6. app/routes.py - Define Routes

This file defines the routes to display the dashboard, create tasks, and manage
projects.

from flask import render_template, redirect, url_for, Blueprint


from app import db
from app.models import Project, Task
from app.forms import TaskForm

main_bp = Blueprint('main', __name__)

@main_bp.route('/')
def index():
projects = Project.query.all()
return render_template('dashboard.html', projects=projects)

@main_bp.route('/task/<int:task_id>')
def task(task_id):
task = Task.query.get_or_404(task_id)
return render_template('task.html', task=task)

@main_bp.route('/create_task/<int:project_id>', methods=['GET', 'POST'])


def create_task(project_id):
form = TaskForm()
if form.validate_on_submit():
task = Task(
title=form.title.data,
description=form.description.data,
deadline=form.deadline.data,
project_id=project_id,
)
db.session.add(task)
db.session.commit()
return redirect(url_for('main.index'))
return render_template('task.html', form=form)
7. HTML Templates in templates/

 base.html: Base template that is extended by other templates.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Task Management Tool</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<header>
<h1>Task Management</h1>
<nav>
<ul>
<li><a href="{{ url_for('main.index') }}">Dashboard</a></li>
</ul>
</nav>
</header>
<div class="content">
{% block content %}{% endblock %}
</div>
</body>
</html>

 dashboard.html: Display the list of projects.

{% extends 'base.html' %}

{% block content %}
<h2>Projects</h2>
<ul>
{% for project in projects %}
<li>{{ project.name }} - <a href="{{ url_for('main.create_task', project_id=project.id) }}">Add
Task</a></li>
{% endfor %}
</ul>
{% endblock %}

 task.html: Display task details and allow editing.

{% extends 'base.html' %}

{% block content %}
<h2>Task Details</h2>
<p><strong>Title:</strong> {{ task.title }}</p>
<p><strong>Description:</strong> {{ task.description }}</p>
<p><strong>Deadline:</strong> {{ task.deadline }}</p>
<p><strong>Status:</strong> {% if task.completed %} Completed {% else %} Not Completed {% endif
%}</p>
{% endblock %}
8. static/style.css - Basic CSS for the App
body {
font-family: Arial, sans-serif;
}

header {
background-color: #2c3e50;
padding: 20px;
color: white;
}

nav ul {
list-style-type: none;
}

nav ul li {
display: inline;
margin-right: 10px;
}

.content {
margin: 20px;
}
h2 {
color: #34495e;
}

Step 4: Run the Application

Once all the files are set up, you can run the app with the following command:

python run.py

You should be able to visit http://127.0.0.1:5000/ and see your Task Management
Dashboard.

Conclusion

In this tutorial, we have created a simple task and project management tool using
Flask and SQLite. You can extend this app by adding features like user
authentication, task deadlines, and prioritization.

To extend your task management app with user authentication, task deadlines,
and prioritization, we will:

1. User Authentication: Implement user registration, login, and logout


functionality using Flask-Login.
2. Task Deadlines: Ensure that tasks have proper deadlines, and they are
displayed in an easy-to-read format.
3. Prioritization: Allow tasks to be prioritized by adding a priority field (low,
medium, high).

Let's break down each of these features.

Step 1: Install Additional Dependencies

First, install the necessary libraries for user authentication:

pip install flask-login flask-bcrypt

Step 2: Update Folder Structure

We will add a new file user.py for handling user-related models and authentication
logic.

task_management_tool/

├── app/
│ ├── __init__.py
│ ├── routes.py
│ ├── models.py
│ ├── forms.py
│ ├── user.py # New file for user management
│ └── __init__.py
├── templates/
│ ├── base.html
│ ├── login.html # New login page
│ ├── register.html # New register page
│ ├── dashboard.html
│ ├── task.html
│ └── logout.html # New logout page
├── static/
│ └── style.css
├── config.py
└── run.py

Step 3: Modify config.py for Flask-Login and Password Security

Update the configuration file to include a SECRET_KEY for sessions and a


SQLALCHEMY_DATABASE_URI for the database.

import os

class Config:
SECRET_KEY = os.urandom(24) # Random secret key for session management
SQLALCHEMY_DATABASE_URI = 'sqlite:///tasks.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
LOGIN_DISABLED = False # Allows user to login

Step 4: Update app/__init__.py to Initialize Flask-Login

We need to initialize Flask-Login and Bcrypt for password hashing.

from flask import Flask


from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect
from flask_login import LoginManager

db = SQLAlchemy()
csrf = CSRFProtect()
login_manager = LoginManager()

def create_app():
app = Flask(__name__)
app.config.from_object('config.Config')

db.init_app(app)
csrf.init_app(app)
login_manager.init_app(app)

from app.routes import main_bp


app.register_blueprint(main_bp)

return app

Step 5: Create the user.py Model for User Authentication

In app/user.py, define the User model and helper functions for authentication.
from flask_login import UserMixin
from app import db
from werkzeug.security import generate_password_hash, check_password_hash

class User(UserMixin, db.Model):


id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), unique=True, nullable=False)
password = db.Column(db.String(200), nullable=False)

def set_password(self, password):


self.password = generate_password_hash(password)

def check_password(self, password):


return check_password_hash(self.password, password)

Step 6: Update app/models.py for Task Prioritization

Add a priority field to the Task model to handle task prioritization (low, medium, high).

from datetime import datetime


from app import db

class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
tasks = db.relationship('Task', backref='project', lazy=True)

class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
description = db.Column(db.String(200), nullable=True)
deadline = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
completed = db.Column(db.Boolean, default=False)
priority = db.Column(db.String(20), default='Medium') # Low, Medium, High
project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False)

Step 7: Update app/forms.py for User Registration and Task Creation

Add forms for user registration, login, and task creation (with priority).

from flask_wtf import FlaskForm


from wtforms import StringField, BooleanField, SubmitField, DateTimeField, SelectField
from wtforms.validators import DataRequired, Length, Email

class TaskForm(FlaskForm):
title = StringField('Title', validators=[DataRequired()])
description = StringField('Description')
deadline = DateTimeField('Deadline', format='%Y-%m-%d %H:%M:%S')
completed = BooleanField('Completed')
priority = SelectField('Priority', choices=[('Low', 'Low'), ('Medium', 'Medium'), ('High', 'High')])
submit = SubmitField('Save Task')

class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = StringField('Password', validators=[DataRequired()])
submit = SubmitField('Login')
class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=4, max=20)])
password = StringField('Password', validators=[DataRequired()])
submit = SubmitField('Register')

Step 8: Update app/routes.py for User Authentication and Task Management

1. User Registration: Allow users to register.


2. User Login: Allow users to log in.
3. User Logout: Allow users to log out.
4. Task Prioritization: Implement task creation with priorities.

from flask import render_template, redirect, url_for, flash, request, Blueprint


from flask_login import login_user, login_required, logout_user, current_user
from app import db
from app.models import Project, Task
from app.forms import TaskForm, LoginForm, RegistrationForm
from app.user import User

main_bp = Blueprint('main', __name__)

@main_bp.route('/login', methods=['GET', 'POST'])


def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user and user.check_password(form.password.data):
login_user(user)
return redirect(url_for('main.index'))
flash('Invalid username or password', 'danger')
return render_template('login.html', form=form)

@main_bp.route('/register', methods=['GET', 'POST'])


def register():
form = RegistrationForm()
if form.validate_on_submit():
hashed_password = generate_password_hash(form.password.data)
user = User(username=form.username.data, password=hashed_password)
db.session.add(user)
db.session.commit()
flash('Your account has been created!', 'success')
return redirect(url_for('main.login'))
return render_template('register.html', form=form)

@main_bp.route('/logout')
def logout():
logout_user()
return redirect(url_for('main.login'))

@main_bp.route('/')
@login_required
def index():
projects = Project.query.all()
return render_template('dashboard.html', projects=projects)

@main_bp.route('/create_task/<int:project_id>', methods=['GET', 'POST'])


@login_required
def create_task(project_id):
form = TaskForm()
if form.validate_on_submit():
task = Task(
title=form.title.data,
description=form.description.data,
deadline=form.deadline.data,
priority=form.priority.data,
project_id=project_id,
)
db.session.add(task)
db.session.commit()
return redirect(url_for('main.index'))
return render_template('task.html', form=form)

Step 9: Create HTML Templates for Login, Register, and Logout


login.html
{% extends 'base.html' %}

{% block content %}
<h2>Login</h2>
<form method="POST">
{{ form.hidden_tag() }}
<div>{{ form.username.label }} {{ form.username }}</div>
<div>{{ form.password.label }} {{ form.password }}</div>
<div>{{ form.submit }}</div>
</form>
{% endblock %}
register.html
{% extends 'base.html' %}

{% block content %}
<h2>Register</h2>
<form method="POST">
{{ form.hidden_tag() }}
<div>{{ form.username.label }} {{ form.username }}</div>
<div>{{ form.password.label }} {{ form.password }}</div>
<div>{{ form.submit }}</div>
</form>
{% endblock %}
logout.html
{% extends 'base.html' %}

{% block content %}
<h2>You have been logged out successfully!</h2>
<a href="{{ url_for('main.login') }}">Login again</a>
{% endblock %}

Step 10: Running the Application

After making these changes, you need to migrate the database for the new User and
updated Task models.

# Enter the Python shell


python

# Create all database tables


from app import db
db.create_all()
# Exit the Python shell
exit()

Now, run the application:

python run.py

You can now:

- Register a user.
- Login as a user.
- Create tasks with a deadline and priority.
- Logout.

### Conclusion

In this extended version, we added **user authentication** (registration, login, and logout), **task
prioritization** (low, medium, high), and ensured tasks had proper **deadlines**. These features will
allow users to manage their projects and tasks effectively. You can further expand the app with more
features, such as role-based access control or advanced task management features like task
dependencies.

To expand the app further with role-based access control (RBAC) and advanced
task management features, such as task dependencies, let's break down the
necessary steps.

Features to Implement

1. Role-Based Access Control (RBAC):


o Users can have different roles (e.g., Admin, Manager, User).
o Each role will have different permissions (e.g., Admins can manage
users, Managers can assign tasks, and regular users can only view
and complete tasks).

2. Task Dependencies:
o A task can depend on another task to be completed before it can start
(e.g., "Task B cannot start until Task A is completed").
o A task should track its dependent tasks and check for completion
before moving forward.

Step 1: Update the User Model for Roles

We will add a role field to the User model to define different types of users. These
roles will determine the user's access to certain functionalities.

Update app/user.py
from flask_login import UserMixin
from app import db
from werkzeug.security import generate_password_hash, check_password_hash
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), unique=True, nullable=False)
password = db.Column(db.String(200), nullable=False)
role = db.Column(db.String(50), default='User') # Add a role field: Admin, Manager, User

def set_password(self, password):


self.password = generate_password_hash(password)

def check_password(self, password):


return check_password_hash(self.password, password)

def is_admin(self):
return self.role == 'Admin'

def is_manager(self):
return self.role == 'Manager'

def is_user(self):
return self.role == 'User'
Update app/forms.py for User Registration (with role)

We will update the Registration Form to allow the Admin to assign roles.

from flask_wtf import FlaskForm


from wtforms import StringField, BooleanField, SubmitField, DateTimeField, SelectField
from wtforms.validators import DataRequired, Length

class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=4, max=20)])
password = StringField('Password', validators=[DataRequired()])
role = SelectField('Role', choices=[('User', 'User'), ('Manager', 'Manager'), ('Admin', 'Admin')]) #
Role selection
submit = SubmitField('Register')

Step 2: Update Routes for Role-Based Access Control

In the routes, we will restrict certain actions based on the user's role. For example:

 Admins can manage users (create, edit, delete).


 Managers can assign tasks.
 Users can only view and mark tasks as complete.

Update app/routes.py for RBAC


from flask import render_template, redirect, url_for, flash, request, Blueprint
from flask_login import login_user, login_required, logout_user, current_user
from app import db
from app.models import Project, Task
from app.forms import TaskForm, LoginForm, RegistrationForm
from app.user import User

main_bp = Blueprint('main', __name__)

# Admin Route to manage users (e.g., create, delete)


@main_bp.route('/admin')
@login_required
def admin():
if not current_user.is_admin():
flash("You do not have permission to view this page.", "danger")
return redirect(url_for('main.index'))
users = User.query.all()
return render_template('admin.html', users=users)

@main_bp.route('/create_user', methods=['GET', 'POST'])


@login_required
def create_user():
if not current_user.is_admin():
flash("You do not have permission to create a user.", "danger")
return redirect(url_for('main.index'))
form = RegistrationForm()
if form.validate_on_submit():
hashed_password = generate_password_hash(form.password.data)
user = User(username=form.username.data, password=hashed_password, role=form.role.data)
db.session.add(user)
db.session.commit()
flash(f'User {form.username.data} created successfully!', 'success')
return redirect(url_for('main.admin'))
return render_template('create_user.html', form=form)

# Task Creation Route (Managers can assign tasks)


@main_bp.route('/create_task/<int:project_id>', methods=['GET', 'POST'])
@login_required
def create_task(project_id):
if current_user.is_user(): # Regular users should not have task creation permissions
flash("You do not have permission to create tasks.", "danger")
return redirect(url_for('main.index'))

form = TaskForm()
if form.validate_on_submit():
task = Task(
title=form.title.data,
description=form.description.data,
deadline=form.deadline.data,
priority=form.priority.data,
project_id=project_id,
assigned_to=current_user.id # Manager assigns task to themselves or others
)
db.session.add(task)
db.session.commit()
flash('Task created successfully!', 'success')
return redirect(url_for('main.index'))
return render_template('task.html', form=form)

Step 3: Implement Task Dependencies

To implement task dependencies, we need to update the Task model to support


dependencies, and we will also add a field to specify tasks that a task depends on.

Update app/models.py for Task Dependencies


from datetime import datetime
from app import db

class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
tasks = db.relationship('Task', backref='project', lazy=True)

class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
description = db.Column(db.String(200), nullable=True)
deadline = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
completed = db.Column(db.Boolean, default=False)
priority = db.Column(db.String(20), default='Medium') # Low, Medium, High
project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False)
assigned_to = db.Column(db.Integer, db.ForeignKey('user.id'))

# Dependencies field (many-to-many relationship)


dependencies = db.relationship('Task', secondary='task_dependencies',
primaryjoin=id == TaskDependency.task_id,
secondaryjoin=id == TaskDependency.dependent_task_id,
backref=db.backref('dependent_tasks', lazy='dynamic'))

class TaskDependency(db.Model):
id = db.Column(db.Integer, primary_key=True)
task_id = db.Column(db.Integer, db.ForeignKey('task.id'), nullable=False)
dependent_task_id = db.Column(db.Integer, db.ForeignKey('task.id'), nullable=False)
Update app/forms.py for Task Dependencies

We will modify the TaskForm to allow users to select which tasks are dependencies.

from flask_wtf import FlaskForm


from wtforms import StringField, BooleanField, SubmitField, DateTimeField, SelectField
from wtforms.validators import DataRequired
from app.models import Task

class TaskForm(FlaskForm):
title = StringField('Title', validators=[DataRequired()])
description = StringField('Description')
deadline = DateTimeField('Deadline', format='%Y-%m-%d %H:%M:%S')
completed = BooleanField('Completed')
priority = SelectField('Priority', choices=[('Low', 'Low'), ('Medium', 'Medium'), ('High', 'High')])
dependencies = SelectField('Dependencies', choices=[], coerce=int) # Populate dynamically
submit = SubmitField('Save Task')

def populate_dependencies(self, project_id):


tasks = Task.query.filter_by(project_id=project_id).all()
self.dependencies.choices = [(task.id, task.title) for task in tasks]
Update app/routes.py to Handle Task Dependencies
@main_bp.route('/create_task/<int:project_id>', methods=['GET', 'POST'])
@login_required
def create_task(project_id):
if current_user.is_user(): # Regular users should not have task creation permissions
flash("You do not have permission to create tasks.", "danger")
return redirect(url_for('main.index'))

form = TaskForm()
form.populate_dependencies(project_id)
if form.validate_on_submit():
task = Task(
title=form.title.data,
description=form.description.data,
deadline=form.deadline.data,
priority=form.priority.data,
project_id=project_id,
assigned_to=current_user.id # Manager assigns task to themselves or others
)
db.session.add(task)
db.session.commit()

# Add dependencies (if any)


if form.dependencies.data:
dependent_task = Task.query.get(form.dependencies.data)
task.dependencies.append(dependent_task)
db.session.commit()

flash('Task created successfully!', 'success')


return redirect(url_for('main.index'))
return render_template('task.html', form=form)

Step 4: Admin Page for Managing Users

Add an Admin page to allow Admin users to manage other users, including their
roles.

Create admin.html Template


{% extends 'base.html' %}

{% block content %}
<h2>Admin Dashboard</h2>
<ul>
{% for user in users %}
<li>{{ user.username }} - Role: {{ user.role

}} {% endfor %}

Step 5: Running the Application

1. Create the database with the new user roles and task dependencies:

python
from app import db
db.create_all()
exit()

2. Run the application:

python run.py

Conclusion

Now, the app supports:

 Role-Based Access Control (RBAC): Different user roles (Admin, Manager,


User) with access permissions.
 Task Dependencies: Tasks can depend on other tasks to be completed
before starting.

You might also like