IntroductionBuilding a Todo app isn’t just about creating a simple checklist; it’s an opportunity to grasp key concepts in web development. In this guide, we’ll explore the significance of models and controllers in the context of a Flask and MySQL-based Todo app.
Section 1: Setting Up the Project
Establishing a clean and organized project structure is crucial for maintainability. The virtual environment ensures dependencies don’t conflict with other projects, and Flask installation sets the foundation for building robust web applications.
python -m venv venv
source venv/bin/activate
venvScriptsactivate
pip install Flask
pip install mysql-connector-python
Section 2: Database Models
Models are the backbone of any database-driven application. Defining a clear and structured model, such as the Todo model in our case, streamlines database interactions and ensures data consistency.
class Todo:
def __init__(self, title, completed=False, id=None):
self.id = id
self.title = title
self.completed = completed
Section 3: Creating Routes and Views
Routes and views define the behavior and presentation of our application. These components dictate how users interact with the app and what they see. Clear route definitions and well-designed views are essential for a smooth user experience.
from flask import Flask, request, jsonify, render_template
import mysql.connector
from app.models import Todo
from app.controllers import *
app = Flask(__name__, template_folder=’../template’)
mysql_config = {
‘host’: ‘localhost’,
‘user’: ‘root’,
‘password’: ‘klaus@17320’,
‘database’: ‘todoDB’
}
def create_connection():
return mysql.connector.connect(**mysql_config)
@app.route(‘/’)
def index():
todos = fetch_all_todos()
return render_template(‘base.html’, todos=todos)
if __name__ == ‘__main__’:
app.run(debug=True)
Section 4: Implementing CRUD Operations
CRUD operations (Create, Read, Update, Delete) are fundamental to database-driven applications. Implementing these operations ensures data integrity and provides users with the necessary functionalities to manage their Todos.
@app.route(‘/todos’, methods=[‘GET’])
def get_todos():
todos = fetch_all_todos()
return jsonify({‘todos’: todos})
@app.route(‘/add’, methods=[‘POST’])
def add_todo():
data = request.form
new_todo = Todo(title=data[‘title’], completed=data.get(‘completed’, False))
created_todo = create_todo(new_todo)
return jsonify({‘message’: ‘Todo created successfully’, ‘todo’: created_todo.__dict__}), 201
@app.route(‘/toggle/<int:todo_id>’, methods=[‘PUT’])
def toggle_completion(todo_id):
try:
toggle_completion_status(todo_id)
return jsonify({‘message’: f’Toggle completion status for Todo with ID {todo_id} successfully’})
except Exception as e:
return jsonify({‘error’: str(e)}), 500
@app.route(‘/delete/<int:todo_id>’, methods=[‘DELETE’])
def delete_todo_route(todo_id):
delete_todo(todo_id)
return jsonify({‘message’: ‘Todo with id {todo_id} deleted successfully’})
Section 5: Models and Controllers Collaboration
Models and controllers work hand in hand. Models handle database interactions and ensure data consistency, while controllers bridge the gap between models and views. This separation of concerns enhances code readability, maintainability, and scalability.
from .app import create_connection
from .models import Todo
def fetch_all_todos():
connection = create_connection()
cursor = connection.cursor(dictionary=True)
cursor.execute(‘SELECT * FROM list’)
todos = cursor.fetchall()
connection.close()
return todos
def create_todo(todo):
connection = create_connection()
cursor = connection.cursor()
cursor.execute(‘INSERT INTO list (title, completed) VALUES (%s, %s)’, (todo.title, todo.completed))
connection.commit()
todo.id = cursor.lastrowid
connection.close()
return todo
def toggle_completion_status(todo_id):
connection = create_connection()
cursor = connection.cursor()
cursor.execute(‘SELECT completed FROM list WHERE id=%s’, (todo_id,))
current_status = cursor.fetchone()
if current_status is not None:
current_status = current_status[0]
new_status = 1 – current_status
cursor.execute(‘UPDATE list SET completed=%s WHERE id=%s’, (new_status, todo_id))
connection.commit()
connection.close()
else:
raise ValueError(f’Todo with ID {todo_id} not found’)
def delete_todo(todo_id):
connection = create_connection()
cursor = connection.cursor()
cursor.execute(‘DELETE FROM list WHERE id=%s’, (todo_id,))
connection.commit()
connection.close()
Section 6: Frontend Integration with JavaScript
Enhance the user experience by integrating JavaScript. This section demonstrates how to send asynchronous requests (AJAX) to the Flask backend using the fetch API.
function addTodo() {
var title = document.getElementById(‘title’).value;
var formData = new FormData();
formData.append(‘title’, title);
fetch(‘/add’, {
method: ‘POST’,
body: formData
})
.then(response => response.json())
.then(data => {
console.log(data.message);
})
.catch(error => {
console.error(‘Error:’, error);
});
}
function deleteTodo(todoId) {
fetch(`/delete/${todoId}`, {
method: ‘DELETE’,
headers: {
‘Content-Type’: ‘application/json’,
},
})
.then(response => response.json())
.then(data => {
console.log(data.message);
})
.catch(error => {
console.error(‘Error:’, error);
});
}
function updateTodo(todoId) {
console.log(‘Updating todo with ID:’, todoId);
fetch(`/toggle/${todoId}`, {
method: ‘PUT’,
headers: {
‘Content-Type’: ‘application/json’,
},
body: JSON.stringify({ }),
})
.then(response => response.json())
.then(data => {
console.log(data.message);
})
.catch(error => {
console.error(‘Error:’, error);
});
}
Section 7: Handling JSON Data
Properly handling JSON data is a best practice in modern web development. Setting the Content-Type to application/json for AJAX requests ensures consistency and compatibility between the frontend and backend components.
{
“error”: “Content-Type must be application/json”
}
Section 8: HTML Page Views
HTML page views are the user interface of your web application. Crafting well-designed and responsive views enhances user experience and complements the backend functionalities.
8.1 HTML Template Structure
Create a clean and structured HTML template for your Todo app. Utilize semantic HTML tags for better accessibility and maintainability.
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Todo App</title>
<link rel=”stylesheet” href=”https://cdn.jsdelivr.net/npm/semantic-ui@2.5.0/dist/semantic.min.css”>
<script src=”https://cdn.jsdelivr.net/npm/semantic-ui@2.5.0/dist/semantic.min.js”></script>
</head>
<body>
<div style=”margin-top: 50px;” class=”ui container”>
<h1 class=”ui center aligned header”>Todo App</h1>
<form class=”ui form” id=”todoForm”>
<div class=”field”>
<label for=”title”>Todo List</label>
<input type=”text” id=”title” name=”title” placeholder=”Enter Todo …..”>
<br>
<button class=”ui blue button” type=”button” onclick=”addTodo()”>Add</button>
</div>
</form>
{% for todo in todos %}
<div class=”ui segment”>
<p class=”ui big header”>{{ todo.ID }} | {{ todo.title }}</p>
{% if todo.completed == 0 %}
<span class=”ui grey label”>Not Completed</span>
{% else %}
<span class=”ui green label”>Completed</span>
{% endif %}
<button class=”ui blue button” onclick=”updateTodo({{ todo.ID }})”>Update</button>
<button class=”ui red button” onclick=”deleteTodo({{ todo.ID }})”>Delete</button>
</div>
{% endfor %}
</div>
// Add javascrpt fetch APT
</body>
</html>
8.2 Displaying Todo ID
Ensure that the Todo ID is correctly displayed in your HTML views. This identifier is crucial for users and helps maintain a clear overview of their Todos.
<p class=”ui big header”>{{ todo.ID }} | {{ todo.title }}</p>
By understanding the importance of models and controllers, you’ve taken a significant step in becoming a proficient web developer. Models ensure database integrity, controllers manage application logic, and together they form the backbone of a robust web application. Keep exploring, experimenting, and building!
I would like to invite all tech enthusiasts to go through my project and collaborate with me and advice for some enhancements to the project. It would be highly appreciated.
The Todo App source code is available on GitHub.
I’m interested to see what you come up with!
So this is it. Do like, comment and share if you like this article.
Do follow me for reading more such technical blogs, content and articles.
Source: hashnode.com