- version : 0.2
- description : add full info for every student .
هذا الالتزام موجود في:
48
app.py
48
app.py
@@ -18,15 +18,25 @@ def init_db():
|
||||
conn = get_db_connection()
|
||||
# Use a 'with' statement to automatically handle closing the connection
|
||||
with conn:
|
||||
# Drop the table if it exists to ensure the new schema is applied
|
||||
conn.execute('DROP TABLE IF EXISTS students')
|
||||
# Create the table with the new, expanded schema
|
||||
conn.execute('''
|
||||
CREATE TABLE IF NOT EXISTS students (
|
||||
CREATE TABLE students (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
student_name TEXT NOT NULL,
|
||||
age INTEGER NOT NULL,
|
||||
parent_name TEXT NOT NULL,
|
||||
phone_number TEXT NOT NULL
|
||||
parent_phone_1 TEXT NOT NULL,
|
||||
parent_phone_2 TEXT,
|
||||
student_phone TEXT,
|
||||
grade TEXT NOT NULL,
|
||||
school_name TEXT NOT NULL,
|
||||
address TEXT NOT NULL,
|
||||
memorizing TEXT NOT NULL
|
||||
)
|
||||
''')
|
||||
print("Database initialized and 'students' table created.")
|
||||
print("Database initialized and 'students' table created with the new schema.")
|
||||
|
||||
# Command to initialize the database from the command line: flask init-db
|
||||
@app.cli.command('init-db')
|
||||
@@ -41,7 +51,8 @@ def init_db_command():
|
||||
def index():
|
||||
"""Renders the main page with the list of students."""
|
||||
conn = get_db_connection()
|
||||
students = conn.execute('SELECT * FROM students').fetchall()
|
||||
# Select all columns to display in the table
|
||||
students = conn.execute('SELECT * FROM students ORDER BY id').fetchall()
|
||||
conn.close()
|
||||
# The 'students' variable is passed to the HTML template
|
||||
return render_template('index.html', students=students)
|
||||
@@ -49,15 +60,25 @@ def index():
|
||||
@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']
|
||||
# Get all the new data from the form submitted in index.html
|
||||
student_name = request.form['student_name']
|
||||
age = request.form['age']
|
||||
parent_name = request.form['parent_name']
|
||||
phone_number = request.form['phone_number']
|
||||
parent_phone_1 = request.form['parent_phone_1']
|
||||
parent_phone_2 = request.form.get('parent_phone_2') # .get() for optional fields
|
||||
student_phone = request.form.get('student_phone') # .get() for optional fields
|
||||
grade = request.form['grade']
|
||||
school_name = request.form['school_name']
|
||||
address = request.form['address']
|
||||
memorizing = request.form['memorizing']
|
||||
|
||||
# Insert the new student record into the database
|
||||
|
||||
# Insert the new student record into the database with all fields
|
||||
conn = get_db_connection()
|
||||
conn.execute('INSERT INTO students (name, parent_name, phone_number) VALUES (?, ?, ?)',
|
||||
(name, parent_name, phone_number))
|
||||
conn.execute('''
|
||||
INSERT INTO students (student_name, age, parent_name, parent_phone_1, parent_phone_2, student_phone, grade, school_name, address, memorizing)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
''', (student_name, age, parent_name, parent_phone_1, parent_phone_2, student_phone, grade, school_name, address, memorizing))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
@@ -65,7 +86,6 @@ def add_student():
|
||||
return redirect(url_for('index'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Initialize the database when the script is run directly
|
||||
init_db()
|
||||
# Run the Flask development server
|
||||
# You can remove the init_db() call from here if you are using the flask command
|
||||
# It's good practice to manage the DB initialization separately.
|
||||
app.run(debug=True)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</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">
|
||||
<div class="container mx-auto p-4 sm:p-6 lg:p-8 max-w-6xl">
|
||||
|
||||
<!-- Header -->
|
||||
<header class="text-center mb-8">
|
||||
@@ -28,62 +28,101 @@
|
||||
</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>
|
||||
<div class="bg-white p-8 rounded-xl shadow-lg mb-8">
|
||||
<h2 class="text-2xl font-semibold mb-6 text-gray-800 border-b pb-4">Add New Student</h2>
|
||||
<form action="/add" method="POST">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<!-- Student Name -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6">
|
||||
<!-- Column 1 -->
|
||||
<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">
|
||||
<label for="student_name" class="block text-sm font-medium text-gray-700 mb-1">Student Name</label>
|
||||
<input type="text" name="student_name" id="student_name" placeholder="Full Name" required class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
<div>
|
||||
<label for="age" class="block text-sm font-medium text-gray-700 mb-1">Age</label>
|
||||
<input type="number" name="age" id="age" placeholder="e.g., 15" required class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</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">
|
||||
<input type="text" name="parent_name" id="parent_name" placeholder="Parent's Full Name" required class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</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">
|
||||
<label for="parent_phone_1" class="block text-sm font-medium text-gray-700 mb-1">Parent Phone 1 (Required)</label>
|
||||
<input type="tel" name="parent_phone_1" id="parent_phone_1" placeholder="e.g., 09xxxxxxxx" required class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
<div>
|
||||
<label for="parent_phone_2" class="block text-sm font-medium text-gray-700 mb-1">Parent Phone 2 (Optional)</label>
|
||||
<input type="tel" name="parent_phone_2" id="parent_phone_2" placeholder="e.g., 09xxxxxxxx" class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
<!-- Column 2 -->
|
||||
<div>
|
||||
<label for="student_phone" class="block text-sm font-medium text-gray-700 mb-1">Student Phone (Optional)</label>
|
||||
<input type="tel" name="student_phone" id="student_phone" placeholder="e.g., 09xxxxxxxx" class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
<div>
|
||||
<label for="grade" class="block text-sm font-medium text-gray-700 mb-1">Grade</label>
|
||||
<input type="text" name="grade" id="grade" placeholder="e.g., 10th Grade" required class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
<div>
|
||||
<label for="school_name" class="block text-sm font-medium text-gray-700 mb-1">School Name</label>
|
||||
<input type="text" name="school_name" id="school_name" placeholder="e.g., Future Generation High" required class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
<div>
|
||||
<label for="address" class="block text-sm font-medium text-gray-700 mb-1">Address</label>
|
||||
<input type="text" name="address" id="address" placeholder="Street, City" required class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
<div>
|
||||
<label for="memorizing" class="block text-sm font-medium text-gray-700 mb-1">Memorizing</label>
|
||||
<input type="text" name="memorizing" id="memorizing" placeholder="e.g., Quran, Part 30" required class="w-full px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</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
|
||||
<div class="mt-8 text-right">
|
||||
<button type="submit" class="px-8 py-3 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-all duration-200 ease-in-out">
|
||||
Add Student Record
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Student List Table -->
|
||||
<div class="bg-white p-6 rounded-xl shadow-md">
|
||||
<div class="bg-white p-6 rounded-xl shadow-lg">
|
||||
<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>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">ID</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Student Name</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Age</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Parent</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Contact Numbers</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Grade</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">School</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Address</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Memorizing</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>
|
||||
<tr class="hover:bg-gray-50 transition-colors duration-200">
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-bold text-gray-700">{{ student['id'] }}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{{ student['student_name'] }}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['age'] }}</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>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">
|
||||
<div class="flex flex-col">
|
||||
<span>P1: {{ student['parent_phone_1'] }}</span>
|
||||
{% if student['parent_phone_2'] %}<span>P2: {{ student['parent_phone_2'] }}</span>{% endif %}
|
||||
{% if student['student_phone'] %}<span>S: {{ student['student_phone'] }}</span>{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['grade'] }}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['school_name'] }}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['address'] }}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['memorizing'] }}</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>
|
||||
<td colspan="9" class="text-center py-6 text-gray-500">No students have been added yet.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم