Python course Β· Module 5: Flask and Web Apps
Frontend basics for Python devs
In this lesson7
Welcome to Module 5! Darwin here with a new chapter - Web Development!
So far you've been working exclusively with the backend - Python, databases, API. Now it's time to learn the frontend - the user interface that visitors see on your website!
Safari Analogy: The backend is like the research laboratory behind the scenes - Python, databases, logic. The frontend is the tourist information center - colorful boards, interactive maps, "See more about lions" buttons!
Why does a Python dev need frontend?
As a Python developer you'll be building web applications - so you need frontend basics!
Frontend = HTML + CSS + JavaScript
- HTML - structure (what's on the page)
- CSS - appearance (how it looks)
- JavaScript - interaction (what happens on click)
Analogy: HTML is the dinosaur skeleton, CSS is the skin and colors, JavaScript is the muscles that allow movement!
HTML - page structure
HTML (HyperText Markup Language) is a markup language defining the structure of a page.
Basic structure
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Safari Database</title>
7</head>
8<body>
9 <h1>Welcome to Safari Database</h1>
10 <p>Species data management system</p>
11</body>
12</html>Structure:
<!DOCTYPE html>- document type declaration<html>- root element<head>- metadata (title, charset, styles)<body>- visible content on the page
Important HTML tags
1<!-- Headings (h1 most important, h6 least) -->
2<h1>Safari Database</h1>
3<h2>African Species</h2>
4<h3>Lion (Panthera leo)</h3>
5
6<!-- Paragraph -->
7<p>The lion is Africa's largest predator...</p>
8
9<!-- Link -->
10<a href="/species/lion">See lion details</a>
11
12<!-- Image -->
13<img src="/static/images/lion.jpg" alt="Lion in Serengeti">
14
15<!-- Unordered list -->
16<ul>
17 <li>Lion</li>
18 <li>Elephant</li>
19 <li>Cheetah</li>
20</ul>
21
22<!-- Ordered list -->
23<ol>
24 <li>Fetch data</li>
25 <li>Process</li>
26 <li>Display</li>
27</ol>
28
29<!-- Button -->
30<button>Add observation</button>
31
32<!-- Form -->
33<form action="/add-species" method="POST">
34 <label for="name">Name:</label>
35 <input type="text" id="name" name="name" required>
36
37 <label for="population">Population:</label>
38 <input type="number" id="population" name="population">
39
40 <button type="submit">Save</button>
41</form>
42
43<!-- Table -->
44<table>
45 <thead>
46 <tr>
47 <th>Species</th>
48 <th>Population</th>
49 <th>Habitat</th>
50 </tr>
51 </thead>
52 <tbody>
53 <tr>
54 <td>Lion</td>
55 <td>120</td>
56 <td>Savanna</td>
57 </tr>
58 <tr>
59 <td>Elephant</td>
60 <td>450</td>
61 <td>Savanna</td>
62 </tr>
63 </tbody>
64</table>
65
66<!-- Div - block container -->
67<div class="species-card">
68 <h3>Lion</h3>
69 <p>Population: 120</p>
70</div>
71
72<!-- Span - inline container -->
73<p>Status: <span class="endangered">Endangered</span></p>HTML attributes
1<!-- class - CSS class -->
2<div class="species-card endangered">...</div>
3
4<!-- id - unique identifier -->
5<div id="lion-details">...</div>
6
7<!-- data-* - custom data attributes -->
8<div class="species" data-id="123" data-population="120">...</div>
9
10<!-- href - link -->
11<a href="https://example.com">Link</a>
12
13<!-- src, alt - images -->
14<img src="image.jpg" alt="Image description">
15
16<!-- placeholder, required - forms -->
17<input type="text" placeholder="Enter name" required>CSS - styling the page
CSS (Cascading Style Sheets) defines the appearance of HTML elements.
Ways to add CSS
1<!-- 1. Inline CSS (not recommended) -->
2<p style="color: green; font-size: 18px;">Text</p>
3
4<!-- 2. Internal CSS (in <head>) -->
5<head>
6 <style>
7 p {
8 color: green;
9 font-size: 18px;
10 }
11 </style>
12</head>
13
14<!-- 3. External CSS (recommended) -->
15<head>
16 <link rel="stylesheet" href="/static/css/style.css">
17</head>CSS selectors
1/* Tag selector */
2p {
3 color: #333;
4 line-height: 1.6;
5}
6
7/* Class selector */
8.species-card {
9 border: 2px solid #ddd;
10 padding: 20px;
11 margin: 10px;
12 border-radius: 8px;
13}
14
15/* ID selector */
16#lion-details {
17 background-color: #f9f9f9;
18}
19
20/* Attribute selector */
21[data-endangered="true"] {
22 border-color: red;
23}
24
25/* Child selector */
26.species-card > h3 {
27 color: #2c5f2d;
28}
29
30/* Hover state */
31button:hover {
32 background-color: #45a049;
33 cursor: pointer;
34}Basic CSS properties
1/* Colors */
2.endangered {
3 color: red;
4 background-color: #ffe6e6;
5}
6
7/* Typography */
8h1 {
9 font-family: 'Arial', sans-serif;
10 font-size: 32px;
11 font-weight: bold;
12 text-align: center;
13}
14
15/* Box model */
16.species-card {
17 width: 300px;
18 height: 200px;
19 padding: 20px; /* Inner spacing */
20 margin: 10px; /* Outer spacing */
21 border: 2px solid #ddd;
22}
23
24/* Flexbox - layout */
25.species-list {
26 display: flex;
27 flex-wrap: wrap;
28 gap: 20px;
29 justify-content: center;
30}
31
32/* Grid - layout */
33.species-grid {
34 display: grid;
35 grid-template-columns: repeat(3, 1fr);
36 gap: 20px;
37}Safari example - styling a species card
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Safari Database</title>
6 <style>
7 body {
8 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
9 background-color: #f4f1de;
10 margin: 0;
11 padding: 20px;
12 }
13
14 h1 {
15 text-align: center;
16 color: #2c5f2d;
17 }
18
19 .species-list {
20 display: flex;
21 flex-wrap: wrap;
22 gap: 20px;
23 justify-content: center;
24 max-width: 1200px;
25 margin: 0 auto;
26 }
27
28 .species-card {
29 background-color: white;
30 border: 2px solid #e0afa0;
31 border-radius: 12px;
32 padding: 20px;
33 width: 280px;
34 box-shadow: 0 4px 6px rgba(0,0,0,0.1);
35 transition: transform 0.2s;
36 }
37
38 .species-card:hover {
39 transform: translateY(-5px);
40 box-shadow: 0 6px 12px rgba(0,0,0,0.15);
41 }
42
43 .species-card.endangered {
44 border-color: #d62828;
45 border-width: 3px;
46 }
47
48 .species-name {
49 color: #2c5f2d;
50 font-size: 24px;
51 margin-top: 0;
52 }
53
54 .badge {
55 display: inline-block;
56 padding: 4px 8px;
57 border-radius: 4px;
58 font-size: 12px;
59 font-weight: bold;
60 }
61
62 .badge-endangered {
63 background-color: #d62828;
64 color: white;
65 }
66
67 .badge-safe {
68 background-color: #4caf50;
69 color: white;
70 }
71 </style>
72</head>
73<body>
74 <h1>Safari Database</h1>
75
76 <div class="species-list">
77 <div class="species-card endangered">
78 <h3 class="species-name">Lion</h3>
79 <p><strong>Population:</strong> 120 individuals</p>
80 <p><strong>Habitat:</strong> Savanna</p>
81 <span class="badge badge-endangered">Endangered</span>
82 </div>
83
84 <div class="species-card endangered">
85 <h3 class="species-name">African Elephant</h3>
86 <p><strong>Population:</strong> 450 individuals</p>
87 <p><strong>Habitat:</strong> Savanna</p>
88 <span class="badge badge-endangered">Endangered</span>
89 </div>
90
91 <div class="species-card">
92 <h3 class="species-name">Giraffe</h3>
93 <p><strong>Population:</strong> 850 individuals</p>
94 <p><strong>Habitat:</strong> Savanna</p>
95 <span class="badge badge-safe">Safe</span>
96 </div>
97 </div>
98</body>
99</html>JavaScript - interactivity
JavaScript adds interaction - reactions to clicks, animations, dynamic changes.
JavaScript basics
1<!DOCTYPE html>
2<html>
3<head>
4 <title>Safari JS</title>
5</head>
6<body>
7 <h1 id="title">Safari Database</h1>
8 <button onclick="changeName()">Change title</button>
9 <button id="addBtn">Add species</button>
10
11 <div id="species-count">Species: 0</div>
12
13 <script>
14 // Variables
15 let speciesCount = 3;
16 const databaseName = "Safari DB";
17
18 // Function
19 function changeName() {
20 document.getElementById("title").textContent = "New title!";
21 }
22
23 // Event listener (better way than onclick)
24 document.getElementById("addBtn").addEventListener("click", function() {
25 speciesCount++;
26 document.getElementById("species-count").textContent = `Species: ${speciesCount}`;
27 });
28
29 // Console log
30 console.log("Page loaded!");
31
32 // Fetch data from API
33 fetch("/api/species")
34 .then(response => response.json())
35 .then(data => {
36 console.log("Data fetched:", data);
37 })
38 .catch(error => console.error("Error:", error));
39 </script>
40</body>
41</html>DOM manipulation
1// Get element
2const title = document.getElementById("title");
3const cards = document.querySelectorAll(".species-card");
4const firstCard = document.querySelector(".species-card");
5
6// Change content
7title.textContent = "New title";
8title.innerHTML = "<strong>Bold title</strong>";
9
10// Change styles
11title.style.color = "red";
12title.style.fontSize = "32px";
13
14// Add/remove classes
15title.classList.add("highlight");
16title.classList.remove("old-class");
17title.classList.toggle("active");
18
19// Create new element
20const newCard = document.createElement("div");
21newCard.className = "species-card";
22newCard.innerHTML = `
23 <h3>Cheetah</h3>
24 <p>Population: 7100</p>
25`;
26
27// Add to page
28document.querySelector(".species-list").appendChild(newCard);
29
30// Remove element
31const cardToRemove = document.querySelector(".species-card");
32cardToRemove.remove();Safari example - interactive list
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Interactive Safari</title>
6 <style>
7 body {
8 font-family: Arial, sans-serif;
9 max-width: 800px;
10 margin: 0 auto;
11 padding: 20px;
12 background-color: #f4f1de;
13 }
14
15 .add-form {
16 background: white;
17 padding: 20px;
18 border-radius: 8px;
19 margin-bottom: 20px;
20 }
21
22 input, button {
23 padding: 10px;
24 margin: 5px;
25 border-radius: 4px;
26 border: 1px solid #ddd;
27 }
28
29 button {
30 background-color: #2c5f2d;
31 color: white;
32 cursor: pointer;
33 border: none;
34 }
35
36 button:hover {
37 background-color: #45a049;
38 }
39
40 .species-card {
41 background: white;
42 padding: 15px;
43 margin: 10px 0;
44 border-radius: 8px;
45 border-left: 4px solid #2c5f2d;
46 display: flex;
47 justify-content: space-between;
48 align-items: center;
49 }
50
51 .delete-btn {
52 background-color: #d62828;
53 padding: 8px 12px;
54 font-size: 14px;
55 }
56
57 .delete-btn:hover {
58 background-color: #9d0208;
59 }
60 </style>
61</head>
62<body>
63 <h1>Safari Database - Interactive List</h1>
64
65 <div class="add-form">
66 <h3>Add new species</h3>
67 <input type="text" id="speciesName" placeholder="Species name">
68 <input type="number" id="speciesPopulation" placeholder="Population">
69 <button id="addBtn">Add</button>
70 </div>
71
72 <div id="speciesList"></div>
73
74 <p><strong>Total species:</strong> <span id="totalCount">0</span></p>
75
76 <script>
77 // Application state
78 let species = [
79 { id: 1, name: "Lion", population: 120 },
80 { id: 2, name: "Elephant", population: 450 },
81 { id: 3, name: "Cheetah", population: 7100 }
82 ];
83 let nextId = 4;
84
85 // Render list
86 function renderSpecies() {
87 const listElement = document.getElementById("speciesList");
88 listElement.innerHTML = "";
89
90 species.forEach(spec => {
91 const card = document.createElement("div");
92 card.className = "species-card";
93 card.innerHTML = `
94 <div>
95 <strong>${spec.name}</strong> - Population: ${spec.population} individuals
96 </div>
97 <button class="delete-btn" onclick="deleteSpecies(${spec.id})">Delete</button>
98 `;
99 listElement.appendChild(card);
100 });
101
102 // Update counter
103 document.getElementById("totalCount").textContent = species.length;
104 }
105
106 // Add species
107 document.getElementById("addBtn").addEventListener("click", function() {
108 const nameInput = document.getElementById("speciesName");
109 const popInput = document.getElementById("speciesPopulation");
110
111 const name = nameInput.value.trim();
112 const population = parseInt(popInput.value);
113
114 if (name && population) {
115 species.push({
116 id: nextId++,
117 name: name,
118 population: population
119 });
120
121 // Clear form
122 nameInput.value = "";
123 popInput.value = "";
124
125 // Re-render
126 renderSpecies();
127 } else {
128 alert("Please fill in all fields!");
129 }
130 });
131
132 // Delete species
133 function deleteSpecies(id) {
134 if (confirm("Are you sure you want to delete this species?")) {
135 species = species.filter(s => s.id !== id);
136 renderSpecies();
137 }
138 }
139
140 // Initial render
141 renderSpecies();
142 </script>
143</body>
144</html>How does it all work together?
HTML β Structure ("what") CSS β Appearance ("how it looks") JavaScript β Interaction ("what happens")
1<!-- HTML - structure -->
2<button id="likeBtn" class="btn">Like it!</button>
3
4<!-- CSS - appearance -->
5<style>
6 .btn {
7 background-color: #4CAF50;
8 color: white;
9 padding: 15px 32px;
10 border: none;
11 border-radius: 4px;
12 cursor: pointer;
13 }
14 .btn.liked {
15 background-color: #f44336;
16 }
17</style>
18
19<!-- JavaScript - interaction -->
20<script>
21 document.getElementById("likeBtn").addEventListener("click", function() {
22 this.classList.toggle("liked");
23 this.textContent = this.classList.contains("liked")
24 ? "Don't like :("
25 : "Like it!";
26 });
27</script>Python devs - what do you need to know?
Minimum frontend for Flask:
- HTML - basics (tags, forms, tables)
- CSS - basics (selectors, box model, flexbox)
- JavaScript - basics (DOM, event listeners, fetch)
You don't have to be a frontend expert - Flask with Jinja2 generates HTML for you!
What you'll do in Flask:
- Creating templates (HTML with Jinja2)
- Basic CSS for styling
- Minimal JS for forms/validation
CSS Frameworks (ready-made styles) will help you quickly create nice interfaces:
- Bootstrap - most popular
- Tailwind CSS - utility-first
- Bulma - simple and lightweight
Summary
In this lesson you learned:
- Why a Python dev needs frontend
- HTML - structure (tags, attributes, forms)
- CSS - styling (selectors, colors, layout)
- JavaScript - interaction (DOM, event listeners)
- How HTML, CSS and JS work together
- Practical Safari examples
Final Safari Analogy: The frontend is the park's information center - colorful boards (CSS), trail maps (HTML), interactive "See more" buttons (JavaScript). The backend is the laboratory behind the scenes (Python + databases)!
In the next lesson Darwin will show you Flask - a microframework for building web applications in Python!
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. What does HTML (HyperText Markup Language) define?
2. Which technologies make up the classic web frontend?
These are 2 of 3 questions for this lesson. Solve the rest in the game.
Hands-on tasks in the game
- Click in order
Arrange the basic HTML document structure in order from the beginning:
- Horizontal ordering
What does a correct first-level heading look like in HTML?
- Horizontal ordering
What does a correct link (anchor) look like in HTML?
- Code editor
Write a basic HTML page with an h1 heading 'Safari Database' and a paragraph with a description.