- version : 0.1
- description : initialize the app
هذا الالتزام موجود في:
1
.gitignore
مباع
Normal file
1
.gitignore
مباع
Normal file
@@ -0,0 +1 @@
|
|||||||
|
__pycache__
|
||||||
71
app.py
Normal file
71
app.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import sqlite3
|
||||||
|
from flask import Flask, render_template, request, redirect, url_for
|
||||||
|
|
||||||
|
# Create a Flask application instance
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# --- Database Functions ---
|
||||||
|
|
||||||
|
def get_db_connection():
|
||||||
|
"""Creates and returns a connection to the SQLite database."""
|
||||||
|
conn = sqlite3.connect('students.db')
|
||||||
|
# Return rows as dictionaries, so we can access columns by name
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
return conn
|
||||||
|
|
||||||
|
def init_db():
|
||||||
|
"""Initializes the database and creates the 'students' table if it doesn't exist."""
|
||||||
|
conn = get_db_connection()
|
||||||
|
# Use a 'with' statement to automatically handle closing the connection
|
||||||
|
with conn:
|
||||||
|
conn.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS students (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
parent_name TEXT NOT NULL,
|
||||||
|
phone_number TEXT NOT NULL
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
print("Database initialized and 'students' table created.")
|
||||||
|
|
||||||
|
# Command to initialize the database from the command line: flask init-db
|
||||||
|
@app.cli.command('init-db')
|
||||||
|
def init_db_command():
|
||||||
|
"""Clear existing data and create new tables."""
|
||||||
|
init_db()
|
||||||
|
|
||||||
|
|
||||||
|
# --- App Routes ---
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
"""Renders the main page with the list of students."""
|
||||||
|
conn = get_db_connection()
|
||||||
|
students = conn.execute('SELECT * FROM students').fetchall()
|
||||||
|
conn.close()
|
||||||
|
# The 'students' variable is passed to the HTML template
|
||||||
|
return render_template('index.html', students=students)
|
||||||
|
|
||||||
|
@app.route('/add', methods=['POST'])
|
||||||
|
def add_student():
|
||||||
|
"""Handles the form submission for adding a new student."""
|
||||||
|
# Get data from the form submitted in index.html
|
||||||
|
name = request.form['name']
|
||||||
|
parent_name = request.form['parent_name']
|
||||||
|
phone_number = request.form['phone_number']
|
||||||
|
|
||||||
|
# Insert the new student record into the database
|
||||||
|
conn = get_db_connection()
|
||||||
|
conn.execute('INSERT INTO students (name, parent_name, phone_number) VALUES (?, ?, ?)',
|
||||||
|
(name, parent_name, phone_number))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
# Redirect back to the main page to see the updated list
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Initialize the database when the script is run directly
|
||||||
|
init_db()
|
||||||
|
# Run the Flask development server
|
||||||
|
app.run(debug=True)
|
||||||
96
templates/index.html
Normal file
96
templates/index.html
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Student Information</title>
|
||||||
|
<!-- Tailwind CSS for styling -->
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<!-- Google Fonts: Inter -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
/* Use Inter as the default font */
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="bg-gray-50 text-gray-800">
|
||||||
|
|
||||||
|
<div class="container mx-auto p-4 sm:p-6 lg:p-8 max-w-4xl">
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
|
<header class="text-center mb-8">
|
||||||
|
<h1 class="text-3xl sm:text-4xl font-bold text-gray-900">Student Management System</h1>
|
||||||
|
<p class="text-gray-600 mt-2">Enter and view student details below.</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Student Entry Form -->
|
||||||
|
<div class="bg-white p-6 rounded-xl shadow-md mb-8">
|
||||||
|
<h2 class="text-2xl font-semibold mb-4 text-gray-800">Add New Student</h2>
|
||||||
|
<form action="/add" method="POST">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
|
<!-- Student Name -->
|
||||||
|
<div>
|
||||||
|
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">Student Name</label>
|
||||||
|
<input type="text" name="name" id="name" placeholder="e.g., Jane Doe" required
|
||||||
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
|
||||||
|
</div>
|
||||||
|
<!-- Parent's Name -->
|
||||||
|
<div>
|
||||||
|
<label for="parent_name" class="block text-sm font-medium text-gray-700 mb-1">Parent's Name</label>
|
||||||
|
<input type="text" name="parent_name" id="parent_name" placeholder="e.g., John Doe" required
|
||||||
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
|
||||||
|
</div>
|
||||||
|
<!-- Phone Number -->
|
||||||
|
<div>
|
||||||
|
<label for="phone_number" class="block text-sm font-medium text-gray-700 mb-1">Phone Number</label>
|
||||||
|
<input type="tel" name="phone_number" id="phone_number" placeholder="e.g., (123) 456-7890" required
|
||||||
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6 text-right">
|
||||||
|
<button type="submit"
|
||||||
|
class="px-6 py-2 bg-blue-600 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200">
|
||||||
|
Add Student
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Student List Table -->
|
||||||
|
<div class="bg-white p-6 rounded-xl shadow-md">
|
||||||
|
<h2 class="text-2xl font-semibold mb-4 text-gray-800">Registered Students</h2>
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="min-w-full divide-y divide-gray-200">
|
||||||
|
<thead class="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Student Name</th>
|
||||||
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Parent's Name</th>
|
||||||
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Phone Number</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="bg-white divide-y divide-gray-200">
|
||||||
|
<!-- Jinja2 loop to populate table rows -->
|
||||||
|
{% for student in students %}
|
||||||
|
<tr>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{{ student['name'] }}</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['parent_name'] }}</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['phone_number'] }}</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<!-- Message shown if there are no students -->
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="text-center py-4 text-gray-500">No students have been added yet.</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
المرجع في مشكلة جديدة
حظر مستخدم