- Full-Stack Section Management Application with Flask and SQLite
- Intro Request for Reviews
- Purpose of the Individual Program
- Purpose of the Groups Program
- Input/Output Requests
- POST Request: Adding a Section
- GET Request: Fetching All Sections
- DELETE Request: Deleting a Section
- List Requests: Database Management
- Working with Lists, Dictionaries, and the Database
- Algorithmic Code Request
- Call to Algorithm: API Requests
- Conclusion
Full-Stack Section Management Application with Flask and SQLite
Introduction
Programming is a collaborative and creative process that brings ideas to life through software development. For this project, we developed an application that allows users to manage sections, which can be dynamically created, retrieved, updated, and deleted (CRUD operations).
In this blog, we will:
- Discuss the purpose of the program and individual features.
- Demonstrate how the frontend interacts with the backend via API requests and how the database handles data.
- Explore lists, dictionaries, and their use in database operations.
- Show algorithmic code for handling requests.
- Detail how the API methods interact with the frontend and backend.
All parts are labled when one prompt explanation starts.
Intro Request for Reviews
Purpose of the Individual Program
My individual contribution I want to disucss focuses on reating an application to manage sections, which show genres recommended by readers. Sections can represent different genres or topics in a system, such as fiction, non fiction, or mystery. The core functionality involves:
- Creating new genres.
- Viewing all genres.
- Editing and deleting genres. These features ensure efficient data management, collaboration, and dynamic content creation.
It also involves the development of the Section CRUD API. This includes:
- Designing RESTful API endpoints using Flask to handle CRUD operations for genres.
- Interacting with an SQLite database to store and retrieve section data.
- Creating a frontend that dynamically interacts with the backend to display, add, edit, and delete genres.
Purpose of the Groups Program
Lit Connect is our group’s dynamic and user-friendly platform designed to foster connections among literature enthusiasts. The website serves as a hub where readers, writers, and book lovers can interact, collaborate, and share their passion for literature.
Key Features of Lit Connect:
Community Engagement:
- Connect with other users through curated book clubs and discussion groups.
- Share thoughts and reviews about favorite books and authors.
- Participate in interactive events like virtual book readings and literature quizzes.
Section Genre Management:
- Easily organize favorite genres into thematic sections such as “Fiction,” “Non-Fiction,” Drama,” and more.
- Each section is dynamically managed to cater to the specific needs of the community.
Input/Output Requests
In this section, we demonstrate how data is handled through frontend API requests and how responses are managed.
Frontend: API Request and Response
The frontend communicates with the backend using HTTP requests. The interaction occurs via GET, POST, and DELETE methods. Below are examples of these interactions:
POST Request: Adding a Section
The user inputs a section name and an optional theme, which is sent to the backend via a POST request.
function addSection() {
const name = document.getElementById('sectionName').value.trim();
const theme = document.getElementById('sectionTheme').value.trim();
if (!name) {
alert('Section name is required!');
return;
}
fetch('http://127.0.0.1:3000/sections', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, theme }),
})
.then(response => response.json())
.then(() => fetchSections()) // Refresh the section list
.catch(error => alert('Failed to add section:', error));
}
The function sends a POST request with the section data to the /sections endpoint. Upon successful addition, the frontend fetches the updated list of sections.
GET Request: Fetching All Sections
This request retrieves all sections stored in the database and dynamically renders them in an HTML table.
function fetchSections() {
fetch(' http://127.0.0.1:3000/sections')
.then(response => response.json())
.then(data => {
const tableBody = document.getElementById('sectionsTable');
tableBody.innerHTML = '';
data.forEach(section => {
const row = `<tr>
<td>${section.id}</td>
<td>${section.name}</td>
<td>${section.theme || ''}</td>
<td>
<button class="button edit" onclick="editSection(${section.id}, '${section.name}', '${section.theme}')">Edit</button>
<button class="button delete" onclick="deleteSection(${section.id})">Delete</button>
</td>
</tr>`;
tableBody.innerHTML += row;
});
})
.catch(error => console.error('Error fetching sections:', error));
}
Explanation: The function sends a GET request to retrieve all sections and dynamically generates HTML table rows with section data.
DELETE Request: Deleting a Section
When the user clicks Delete, the section is removed from the database using the DELETE method.
function deleteSection(id) {
if (!confirm('Are you sure you want to delete this section?')) return;
fetch(`http://127.0.0.1:3000/sections${id}`, { method: 'DELETE' })
.then(response => response.json())
.then(() => fetchSections()) // Refresh the section list
.catch(error => alert('Failed to delete section:', error));
}
Explanation: A DELETE request is sent to the /sections/{id} endpoint to remove the section from the database.
List Requests: Database Management
The backend uses SQLite for data persistence. SQLAlchemy ORM is employed to interact with the database. The Section model defines the structure of the sections and provides methods for CRUD operations.
Database Initialization and Testing
db_init: Initializes the database and creates the necessary tables.
def init_db():
if not os.path.exists('./instance/volumes'):
os.makedirs('./instance/volumes')
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS sections (
id INTEGER PRIMARY KEY AUTOINCREMENT,
_name TEXT NOT NULL UNIQUE,
_theme TEXT
)
''')
conn.commit()
conn.close()
Explanation: The init_db() function ensures the sections table exists in the database. If not, it creates the table.
- db_restore and db_backup: Handle data creation, backup, and restoration. This ensures the database can be reset or restored from backup files.
def db_restore(data):
sections = {}
for section_data in data:
_ = section_data.pop('id', None) # Remove 'id' from section_data
name = section_data.get("name", None)
section = Section.query.filter_by(_name=name).first()
if section:
section.update(section_data)
else:
section = Section(**section_data)
section.create()
db.session.commit()
return sections
Working with Lists, Dictionaries, and the Database
Use of Lists and Dictionaries
- Lists: We store all sections in a list. For example, when retrieving sections from the database, they are stored in a list format before being displayed on the frontend.
sections = Section.query.all()
sections_list = [section.read() for section in sections]
- Dictionaries: The read() method in the Section class converts section data into a dictionary. This allows data to be easily converted into JSON for API responses.
def read(self):
return {
'id': self.id,
'name': self._name,
'theme': self._theme
}
Algorithmic Code Request
API Methods for CRUD Operations
The backend API has routes for performing the following CRUD operations:
- GET: Retrieve a section by ID.
- POST: Add a new section.
- PUT: Update an existing section.
- DELETE: Remove a section by ID.
POST Method: Create Section
class SectionAPI(Resource):
def post(self):
data = request.get_json()
section = Section(name=data['name'], theme=data.get('theme'))
section.create()
return jsonify(section.read())
- Parameters: The request body contains the section data (name and theme).
- Return type: The response is a JSON object containing the created section.
Sequencing, Selection, and Iteration
In the update() method of the Section class, we demonstrate sequencing (updating attributes), selection (checking which attributes are provided), and iteration (iterating over sections).
def update(self, inputs):
if 'name' in inputs:
self._name = inputs['name']
if 'theme' in inputs:
self._theme = inputs['theme']
db.session.commit()
- Sequencing: The update process is sequential — first, check the inputs, then update attributes accordingly.
- Selection: The code checks if name and theme are provided before updating.
- Iteration: The Section.query.all() method returns all sections, which are iterated to display data.
Call to Algorithm: API Requests
Frontend and backend communicate through API calls. The frontend sends GET, POST, and DELETE requests using fetch().
Making API Calls with fetch()
GET Request: Fetch Sections
fetch('http://127.0.0.1:3000/sections')
.then(response => response.json())
.then(data => {
console.log(data); // Handle the data
})
.catch(error => console.error('Error:', error));
- Response Handling: The response is processed with .json(), and the data is displayed or logged.
Handling Errors
Error handling ensures that the frontend properly reacts to failed requests (e.g., if the backend is down or the data is malformed).
fetch('')
.then(response => {
if (!response.ok) throw new Error('Failed to fetch sections');
return response.json();
})
.catch(error => alert('Error:', error));
Conclusion
This blog detailed the full-stack Section Management Application that I created:
- Frontend handles API requests and responses with JavaScript.
- Backend implements CRUD operations using Flask and SQLAlchemy.
- Database stores and manages sections with SQLite.
- We demonstrated API requests using fetch(), error handling, and how the Section model handles data.
- By integrating these elements, we’ve created a scalable, interactive application that can manage data efficiently and seamlessly.