Python Web Development - Lecture
Python Web Development - Lecture
Every website seen online starts with the same foundation. That’s why developers must understand
how the web works, setting up the right tools and learning by building. Here’s an outline of what
beginners should know before they start, what tools they need, and how to take the first practical
steps toward becoming a web developer.
Before learning web development, it helps to have a few basic skills and concepts in place.
Most importantly, web development requires consistency. Regular practice, even in small amounts,
leads to faster progress than occasional bursts of study.
Learning web development requires both hardware and software tools. These tools form the
foundation for both learning and building real projects.
Hardware: A reliable laptop or desktop computer with at least 8GB of RAM and a stable internet
connection is enough for most beginners. Higher specifications may be needed later for larger
projects or complex applications.
1
4.2.1 Software
Web browser: A modern browser such as Google Chrome, Mozilla Firefox, or Microsoft Edge is
essential for testing websites. Each of these browsers includes developer tools that allow inspection
of elements, layout, and code behavior.
Code editor: Applications like Visual Studio Code, Sublime Text, or Atom are used to write and
edit code. Visual Studio Code is especially popular because it’s free and supports many
programming languages and extensions.
Version control: Git is the most widely used system for tracking code changes. Beginners can
create a free GitHub account to store their projects online and collaborate with others.
Programming languages and tools: For front-end development, HTML, CSS, and JavaScript are
the starting point. For back-end development, a language such as Python, PHP, Java, or [Link] is
needed, along with a database like MySQL or PostgreSQL.
Design and testing tools: Figma (for design), Postman (for testing APIs), and simple text editors
or browser extensions for checking accessibility and responsiveness can be helpful as skills
progress.
Hosting services: Platforms like Netlify or Vercel allow beginners to publish small websites online
easily and for free.
Web development is the process of creating websites that allow users to view and interact
with content over the Internet. Web development includes many different aspects, including
the creation of a website’s design and code to create a functioning website.
Web development is the process of building and maintaining websites and web applications.
This includes everything from markup and coding to scripting, network configuration, and
CMS development.
If someone wants to get started with web development, a big part of that will be learning various
programming languages. Depending on their focus, these could be front-end languages like
2
HTML, CSS, and JavaScript, or back-end languages like Python, PHP, Java, Ruby, and so on.
Front-end development focuses on the visual and interactive parts of a website, while back-end
development handles the server-side logic and databases.
However, learning programming languages isn’t the only part of website development. It’s also
important to understand how the web works at a basic level, especially for anyone interested in
back-end website development.
The first steps in web development involve learning how websites are built and displayed in a
browser. Before coding, understand how a browser requests data from a server and displays it as a
webpage. This basic flow shows how HTML, CSS, and JavaScript work together.
Start with HTML. HTML defines a website’s structure, allowing developers to feature text, links,
images, and sections on web pages. Beginners can practice by building simple pages with
headings, paragraphs, and navigation links.
Learn CSS for styling: CSS shapes a site’s look with colors, fonts, and layouts. Learning Flexbox,
Grid, and responsive design helps pages adjust smoothly to any screen size.
Add interactivity with JavaScript: JavaScript brings sites to life. Start with simple interactions like
toggling elements, validating forms, or updating content dynamically.
Build small projects: Practice by creating small, focused projects, like a personal portfolio, a to-
do list, or a landing page, to apply and reinforce new skills.
Learn to use version control: Use Git to track changes, fix errors, and collaborate. Platforms like
GitHub or GitLab also serve as online portfolios for sharing work.
Publish a first website: Deploying a project to the web is an exciting milestone. Services like
Netlify, Vercel, or GitHub Pages make it simple to upload files and generate a live website link.
As learners gain confidence, they can explore frameworks such as React (for front-end) or Express
(for back-end) to handle more advanced projects. Over time, these skills combine to form a
complete understanding of how modern websites and applications are created and maintained.
3
4.3.2 Importance of web development
1. It brings businesses to life: Web development is a critical part of bringing business ideas to
life. In the 21st century, a solid web presence is essential for any business. This is because
it gives potential customers a glimpse into the company’s culture and values, whilst also
helping with branding and marketing. It also provides customers with a consistent
experience across different platforms.
2. Web development is also important because it can help you stand out from competitors
who aren’t as tech-savvy. If your website looks dated or unprofessional, customers may be
turned off by your brand, even if they’re interested in your products or services.
3. It’s a way of building relationships with customers: Web development is important for
building relationships with customers because it allows you to meet your customers’ needs
in a way that makes sense to them. If your website isn’t easy to use, if it looks outdated, or
if it doesn’t do what you promised it would do, then you may lose the trust of your
customers. However, if you have a great website that meets all of their needs and has
features, they’re excited about, then they’re going to come back again and again.
4. It’s a way of creating more leads and sales: Web development is important for creating
more leads and sales because it makes it easy for customers to find your business online.
If you don’t have a website, then people can’t find you when they go looking, and they’ll
probably just go somewhere else. This can be especially problematic if you’re trying to
reach out to a new demographic or appeal to a new market.
5. It’s a way of differentiating your business from competitors: Web development is important
for differentiating your business from competitors because it can help you stand out from
the crowd. If you have a website that is well-designed, easy to navigate, and visually
appealing, you will be more likely to attract customers than similar businesses that don’t
have these features.
6. With a website, your company can also offer more information about itself than it could
through print advertising alone. This can help you build trust with potential customers by
showing them in-depth the products and/or services that you can provide them with.
7. It’s a way of increasing traffic, engagement and conversion rates for a website: Web
development is a way of increasing traffic, engagement and conversion rates for a website
because it can help you to create a site that is easy to navigate. This will help users to find
4
what they’re looking for quickly, which can increase the likelihood that they will return to
your site in future.
8. The more effective your web development is, the more likely it is that you will have
positive interactions with your audience. This can encourage users to share content on
social media and encourage others to be captivated by your content and subsequently visit
your website.
9. It can help increase brand awareness and loyalty among existing customers: Web
development can help increase brand awareness and loyalty among existing customers in
a variety of ways. For example, websites that are designed to be intuitive and easy to use
will create an enjoyable experience for users, which can help them develop a positive
association with the brand. Also, if a website is easy to navigate, it will make it easier for
customers to find what they’re looking for and make purchases.
Web development can also help customers build relationships with your business. For example,
social media platforms can be used to share news about new products or services. This helps build
trust between you and your customers because they’ll feel like they’re getting inside information.
As beginners progress, they often start to specialize. Web development covers several distinct
paths, each focusing on a different layer of how websites and web applications work. Some
developers concentrate on what visitors see, others on the logic and data that power the site behind
the scenes, and some work across the full spectrum.
5
The table below outlines the main types of web developers, what each one does, and the
programming languages and technologies commonly used in their work.
Type of
What They Do Languages and Tools to Know
Developer
Focuses on the part of a website that users Core languages: HTML, CSS,
interact with directly, e.g., layout, navigation, JavaScript.
6
Tools: Figma, Adobe XD, Sketch,
Canva.
Focuses on the visual design and user
Web Languages: Basic HTML and CSS
experience of a website. Ensures that the
designer/UI for layout adjustments.
website is easy to navigate, visually
developer
consistent, and aligned with brand identity. Knowledge: Design systems,
typography, color theory,
accessibility.
Builds and maintains online stores. Handles JavaScript, PHP, Liquid (Shopify),
E-commerce payment gateways, product catalogs, or React (for headless commerce).
developer shopping carts, and integrations with CRM or Platforms: Shopify,
ERP systems. WooCommerce, Magento,
BigCommerce.
7
APIs: Stripe, PayPal, Square.
Web development and web programming sound very similar — and they are. But, there’s one very
important distinction.
Web development refers to the overall process of creating websites or web applications, including
the project’s design, layout, coding, content creation, and functionality. It involves using a
combination of programming languages, tools, and frameworks to bring a website or web
application to life. Web development may also encompass project management activities, such as
fielding development requests from stakeholders or freelance clients.
Web programming, on the other hand, specifically refers to the coding and scripting of a website,
whether the front-end or back-end. It primarily involves writing code to handle data, process user
inputs, and generate dynamic content.
A web programmer will rarely, if ever, handle a large web development project from end to end.
They may build a certain section of a site or troubleshoot bugs.
Understanding this difference has been crucial in web career path, allowing one to appreciate the
depth and breadth of skills required in the world of web creation. It's a reminder of the diverse
talents and expertise that come together to make the digital world what it is today.
Define 1: A website is a collection of interconnected web pages hosted on a web server and
accessible via the internet. Identified by a unique web address (URL), websites contain text,
images, and videos, and serve purposes ranging from online shopping to sharing information and
entertainment.
Define 2: A website is a group of connected pages hosted on a server and accessed through a
browser using a domain name.
8
Define 3: A website is a place on the internet where you can easily post information about yourself,
your business or topics you're passionate about. It's like having your own corner of the web to
showcase your ideas an connect with others.
Websites are a key part of everyday life, helping people stay informed, shop online, share ideas
and connect with others. They serve as online spaces for communication, learning, entertainment
and business. Depending on who’s creating it, the purpose of a website can vary:
• Sharing information: Many websites exist simply to provide people with information.
Think about your local library, city government or school, they all use their websites to
keep you in the loop. These sites are all about making important details accessible to the
public.
• Business and online sales: Companies rely on websites to present their products or
services, handle transactions and offer customer support. Ecommerce features like
shopping carts and secure payments make it easy for customers to shop online.
• Personal expression and blogging: Got a story to tell, a hobby you're passionate about or
a portfolio of work you're proud of? A personal website or blog is the perfect place to share
it. This is your corner of the internet where you can express yourself freely and put your
creative work on display.
• Entertainment and media: Websites provide access to videos, music, games and news.
Platforms for streaming or reading online content make entertainment easy to enjoy
anytime, anywhere.
• Community and social connection: Online forums, social networks and groups let people
meet others with shared interests, discuss topics and build communities online.
The first thing to understand is the internet and the web that provide a ground for websites. The
internet is the technology or infrastructure connecting computers and facilitating information
sharing. The web is the system that enables information sharing using the internet. It encompasses
9
digital documents, websites, webpages, media and more. To view web content, we use web
browsers like Google Chrome, Internet Explorer, Microsoft Edge, Mozilla Firefox or Safari.
When you enter a web address or domain name into your browser, your computer sends a request
to the hosting server. This request passes through the Domain Name System (DNS) to look up the
server's internet protocol (IP) address. The web service uses protocols like Hypertext Transfer
Protocol (HTTP), Hypertext Transfer Protocol Secure (HTTPS) and File Transfer Protocol (FTP)
to transmit information and files over the web.
Once the server receives the request, it sends back the requested webpage, along with images and
other files, to your computer. The browser then displays the webpage using technologies like
HyperText Markup Language (HTML) and Cascading Style Sheets (CSS). These technologies
structure and present the information on the screen. Website loading time depends on a range of
factors like server speed, internet connection quality and website size and complexity.
10
4.6.2 Difference between website, webpage and web server
Understanding the distinctions between a website, webpage and web server is key for effective
navigation in the digital landscape. Let's use a simple analogy, imagine a bustling marketplace.
The website is like the marketplace itself, and each webpage is a unique stall or shop within it.
Similar to a marketplace, each webpage offers different products, information, images and
services, just like the goods in a shop. Now, picture the internet as the city where the marketplace
is located, a vast network connecting countless marketplaces (websites). It's like exploring a city
full of interconnected markets, each with its own offerings.
Webpage
A webpage is a single document or page within a website. Websites can have multiple webpages,
all linked together by hyperlinks, to display a cohesive website. The page you're currently on is a
webpage. When you go to the home page, you're on a separate webpage, but still within the same
website.
Web server
A web server is a computer that stores and delivers webpages to users when they request them. It
is the physical location where all the files and data for a website are stored. When someone types
in your website's URL, the server gets the necessary files and displays them to create the webpage.
Website
A website is a collection of webpages that are accessed with a single domain name or URL. It
includes all the individual pages, multimedia details and files stored on a web server. Websites are
11
built using languages like HTML, CSS and JavaScript to make visually appealing layouts and
functionality.
A website is a collection of webpages hosted on a web server. In order to create a website, you
need several components. Here’s what you need to get started:
Domain name
To reach your site, individuals type in a unique web address that typically reflects your business
or brand name and ends with a domain extension like .com, .org, or .net. Registering your website
name with a domain registration company, also known as a domain registrar, is necessary to secure
this distinctive internet address.
Domain extension
Also known as top-level domains (TLD), domain extensions can quickly identify specific elements
of a website like its main purpose, owner or geographic location.
Webpages
Webpages, also known as individual documents within a website, present information to users.
Each webpage should serve a specific purpose and contribute to the overall user experience by
providing valuable material, images and interactive elements. Some websites may be concise and
focused, with only a few pages, while others offer an array of information and services to cater to
diverse user needs.
12
Web host
This is the service that stores your website's files and makes them accessible to users on the
internet. By choosing the appropriate plan for hosting a website, you can optimize performance,
enhance security and provide an exceptional usability to your visitors.
URL address
The address of a website is also known as the Universal Resource Locator (URL). When a user
wants to open a website then they need to put the URL of the website into a web browser and the
requested website is delivered by the web server. The URL of the Wix Blog for example,
[Link] is composed of three parts:
1. Protocol identifier: Defines the protocol used to access the webpage (usually HTTP or
HTTPS)
2. Server name: Refers to the domain name and extension where the web server is located
([Link])
3. File name: Indicates the specific page or resource on that web server (blog)
Homepage
The homepage is a very common and important part of the website. It serves as the initial point of
contact for viewers, setting the tone and guiding them to explore the rest of the website. Thinking
through and making a homepage not only showcases the brand's identity but also directs users to
other relevant pages.
Navigation structure
Website navigation is the order of pages and the collection of links that connect them. When done
correctly, it creates a smooth and intuitive browsing. Typically, this structure is supported by one
or more menus, strategically placed to make it easy for users to find what they need and move
around the sections of the website.
13
Website templates
A website template is a pre-made design that includes the layout, color scheme, font choice and
all visual elements. It's like a ready-to-use blueprint for your brand's online presence. With Wix's
website builder, you'll find a wide range of templates, from striking photography website templates
to stylish blog templates. These templates can be customized to fit your brand and content needs.
Multimedia elements
These include a wide range of multimedia details such as images, videos, audio files and interactive
website features like animations and adaptive content. When used correctly, these elements can
make a website engaging, informative and visually appealing.
Content
Content is the information you put on your website to inform, guide, or influence visitors. This
information can be presented with text, images, videos or audio recordings. Similar to website
design, the primary responsibility of content is to keep people engaged, resulting in longer stays
and repeat visits to your site.
When it comes to creating your website, you'll face an important decision: choosing between a
static vs dynamic website. This choice will affect how your webpages are stored and delivered to
users in their browsers. Let's take a closer look at these website structures.
Static websites
A static website is a collection of pre-written webpages that are displayed as published. These sites
aren't interactive, meaning the material on each page remains the same until manually updated.
The information and appearance of static websites remain consistent for all viewers, regardless of
14
their browsers, locations or devices. Often, businesses opt for static websites to establish a simple
online presence, as they are cost-effective without requiring server-side processing in multiple
languages.
While static webpages can't take input from users, they can still contain animations and clickable
elements like hyperlinks or navigation buttons. This makes them a popular choice for portfolio and
catalog sites.
Dynamic websites
Dynamic websites are more flexible and user-friendly. They can change information and
appearance based on several factors, including the time of the day, visitor’s location, language
preferences, past interactions with the site or device type. With these sites, the web server processes
data in real-time to generate customized pages for each visitor. Dynamic websites can interact with
users through forms, surveys, quizzes and other interactive factors that require server-side
processing.
This makes dynamic websites most suited for eCommerce business, social media, ticket booking
and forums. These sites also allow individuals to set up accounts, login and access personalized
information or services.
[Link] is a popular example of a dynamic site. Its front page shows product
recommendations to visitors based on their locations, purchases and search history.
2. What is an IP address?
An Internet Protocol (IP) address is a unique string of numbers. Each device has an IP address to
distinguish itself from the billions of websites and devices connected via the Internet.
The IP address for HubSpot is currently [Link]. Anyone can find a website’s IP address
by visiting a site like Site 24x7 or by using Command Prompt on Windows or Network Utility >
Traceroute on MacBooks.
15
For instance,
On Windows
nslookup [Link] OR
ping [Link]
Example:
nslookup [Link]
Output:
Server: your-dns-server
Address: [Link]
Non-authoritative answer:
Name: [Link]
Address: [Link]
If this sounds new, that’s because most people have been using domain names to reach websites.
While a website can be accessed using its IP address, most internet users prefer to use domain
names or search engines.
Domain names are connected to website server IPs using something called the Domain Name
System (DNS). To be a web developer, it's essential to understand how DNS works.
Hyper Text Transfer Protocol (HTTP) is what connects a website request to the remote server that
houses all website data. It’s a set of rules (a protocol) that defines how messages should be sent
over the internet. It allows users to jump between site pages and websites.
16
If a person types a website into a web browser or searches for something through a search engine,
HTTP provides a framework so that the client (computer) and server can speak the same language
when they make requests and responses to each other over the internet.
It’s essentially the translator between the web user and the internet. HTTP reads a website request,
reads the code sent back from the server, and translates it into a visible website.
Understanding HTTP is important for all aspects of web development, but it's especially essential
for anyone interested in back-end development.
The Internet has become a critical part of almost every part of our society — it provides
information, communication, and entertainment to billions of people every day, and enables
coordination and collaboration between people and business across the globe. Unfortunately, this
crucial piece of infrastructure is poorly understood by a large majority of the population; the
myriad of technologies (both hard and soft) that let your laptop connect to your bank or to your
mom’s Skype window could just as well be magic as far as average person in the street is
concerned.
For many other vital technologies in today’s world, this is not really a problem. Most people don’t
know how to fix their car or how to build a house, and few people are complaining about that. The
Internet is different. It is, despite what it may seem, still in its infancy, and there is a lot of debate
about how it should work, and more importantly, how it should be regulated. This is an important
conversation to have, but in order to make sensible decisions, it is necessary that all participants
are sufficiently informed about the topics being discussed. So far, we have seen many examples
where this is not the case, and this could be directly harmful to the future of the Internet as we
know it.
This post aims to help inform and guide those who wish to (or should) expand their understanding
of this extraordinary communication channel, in a way that is digestible without prior knowledge
of Computer Science. Since the Internet is a fairly complex beast, we will touch on many topics
over a short amount of time, so the depth will naturally be somewhat limited. I will provide links
17
to further reading materials for each topic so the interested reader can continue the journey on their
own.
With a system as deep and wide as the Internet, it is hard to decide exactly where to start. Most of
the pieces are interlinked, and often in very subtle ways. In the interest of making the topic easier
to comprehend, we will start with a fairly high-level overview, and then dive into each individual
component as we go along. Our journey starts with a user called Alice. Alice owns a laptop, and
wants to send e-mail to a person called Bob. Bob uses GMail, and so he will read the e-mail from
Alice by going to [Link] with his Web Browser. By the end of this article, my hope is that you
will understand all the steps taken by the various parts of the Internet “stack” (a stack is simply a
combination of technologies) from Alice presses “Send” in her e-mail client until Bob can read
her e-mail.
When Alice presses “Send”, her laptop’s first task is to figure out how to reach Bob. To make our
example more concrete, let us say that his e-mail address is bob@[Link]. This address tells
Alice’s computer that “bob” is Bob’s username, and that his account is managed by the server
[Link]. A server is simply a machine somewhere on the Internet that provides some service
(e-mail in this case) to remote users. Given this information, Alice’s e-mail program now needs to
somehow start talking to the [Link] server to give it Alice’s e-mail to Bob.
The first step in this process is for Alice’s machine to find [Link]’s Internet Protocol address,
or IP address for short. To give a real-world analogy, imagine that you are sending a package to
Google. You might say that you’re sending it to “Google’s Headquarters”, but on the package
itself, you have to put a so-called routable address like “1600 Amphitheatre Pkwy, Mountain
View, CA 94043, USA”. The former is a handy shortcut, like [Link], but in order to actually
get something there, you need to give the full address so that whomever is carrying your package
can find the right destination.
Addresses (IPs) on the Internet are sequences of numbers, either on the form [Link] (IP
version 4), or on the form 2001:418:1425:28b::255e (IP version 6). The former is slowly being
dropped in favor of the latter, as the latter allows many more unique addresses (IPv4 has only four
numbers from 0-255, so approximately 4 billion in all, whereas IPv6 has many more
18
combinations). We will get back to how these numbers are used to route Alice’s e-mail, but for
now, let us concentrate on the problem of how Alice even learns the address of [Link].
[Link] is known as a domain name on the internet. You have likely seen many of these, as
they are what you use to access most websites (i.e. the part that goes between http:// and the first /
in your Internet browser). The translation from a domain name to an address is done using what is
known as the Domain Name Systems, or DNS. To figure out the address associated with a particular
domain name, your machine will contact a DNS server, and ask it “what is the address of
[Link]?”, and it will in return tell you the address (if it knows it). At this point, the attentive
reader might realize that there’s a potential for an infinite loop here — how would you know the
address of the DNS servers? We’ll get back to this when we talk about DHCP later, but for now,
imagine that every machine already knows the address of at least one DNS server, so there is no
need to look one up.
DNS is a large topic in and of itself, and many of the discussions regarding internet censorship and
access control are based heavily on DNS. Unfortunately, many of those who discuss these topics
do not understand the fundamentals of DNS, which complicates the discussion significantly. In
particular, many of the misunderstandings stem from the belief that refusing to look up a particular
domain name will make it inaccessible on the Internet.
So, now Alice’s computer knows the address of the server responsible for handling Bob’s mail.
Now what? Well, the first thing to realize is that Alice’s machine also has an IP address. Every
machine connected to the Internet is accessible in some way through one (or more) IP addresses.
When you connect to a network, your machine will (usually) run a protocol known as the Dynamic
Host Configuration Protocol, or DHCP.
DHCP dictates that when a machine connects to a network (and doesn’t yet have an IP address), it
should send out some specially formatted transmissions saying that it would like to be given an
address. If there is a DHCP server on the same network (this is usually the modem you got from
your Internet Service Provider (ISP), or the wireless router (the box with antennas) that you have
standing somewhere in your home or office), it will hear this transmission, pick an unused IP
address, and transmit it back. When your machine hears this response, it will adopt the contained
19
IP address. The DHCP machine will usually also include with the IP address the address of another
box on the network that can talk to the Internet (usually its own), and the IP addresses of some
DNS servers.
The Internet-connected box on the network is referred to as a gateway, and any time your machine
wants to talk to a remote machine, it sends its transmission through the gateway. You can think of
it as your local post office. Whatever machine your machine wants to talk to will have a similar
setup, with its own gateway, or local post office. For now, let us assume that the gateways can talk
directly to each other, as though they had a single cable connecting them together physically.
Furthermore, the Internet is what is known as a packet-switched network. This means that
messages are sent in packets of limited size, and a message that is larger than that maximum size
will be split into multiple packets and will have to be re-assembled at the other end. Each of these
smaller packets are routed individually through the Internet on their way to their final destination
([Link] in our example).
To send a message to [Link], Alice’s machine first needs to establish a connection with the
machine at [Link]’s address. This is done using the Transmission Control Protocol, or TCP.
TCP is what is known as a reliable, in-order protocol; in other words, what goes in on one end will
come out the same way in the other end. A protocol is needed (as opposed to just stuffing in all
your packets) because the Internet can be a dangerous and unpredictable place; if you naively send
packets from one side to another, only some will make it through intact, and those that do will
often be shuffled along the way and arrive out-of-order. TCP has a number of mechanisms in place
to piece back together the original message, including asking for missing pieces, and re-ordering
them correctly. There exists another protocol, the User Datagram Protocol, or UDP, that is
commonly used for games or video conferencing where speed is more important than reliability.
UDP simply transmits the packets one at the time, with no reassembly or retransmission at the
receiving end. We will not discuss UDP further in this post.
With this connection established, Alice’s machine can now start sending the message to
[Link]. However, much like with real mail, she needs to put it in an envelope that gives the
recipient’s name, and sender’s address, the subject line, etc. (the destination address is
20
automatically added by the IP “layer”). For this, we have the Internet Message Format, or IMF. It
dictates that an e-mail should be preceded with a number of key/value pairs on the form Key:
Value, and defines some standard ones like From: , Subject:, and To:. Alice’s e-mail message will
therefore look something like
To: bob@[Link]
From: alice@[Link]
Subject: Hello there
Okay, surely we are ready to actually send the message to [Link] now? Well, turns out there’s
one more thing we have to cover. The Internet doesn’t know about such sophisticated things as
letters (or “characters” in more technical terminology), it only knows about bits (0s and 1s), and
bytes (a sequence of eight 0s and 1s). Thus, we somehow have to convert our text message above
into bytes in such a way that [Link] can reassemble the text on the other end. A number of
standards exist for this purpose, but we will stick to the basics and use the widely adopted American
Standard Code for Information Interchange, or ASCII. ASCII essentially defines a table that can
be used to look up the numerical value of a given letter or symbol. This numerical value is in the
range 0-127, which means that it fits in a single byte.
Since ASCII can only represent 128 letters and symbols, it usefulness is restricted mostly to
American correspondence. Some variations have been proposed that uses 256 such mappings (so
they also fit in a single byte), and include more European letters and symbols such as æøå. These
are known as the ISO 8859 family of standards. More modern systems have moved to the Unicode
standard, and specifically the UTF-8 encoding scheme, which can represent practically every letter
and symbol in use on Earth by using more than a single byte per character.
Finally, we can now send the e-mail to [Link]. We take Alice’s encoded e-mail, and we ship
it over our connection to [Link]. Technically, there is another small protocol being used that
21
dictates how to talk to a mail server, called the Simple Mail Transfer Protocol, or SMTP, but it is
of little relevance to us right now.
At this point, [Link] have received Alice’s e-mail, and it will go off and do whatever it needs
to do to scan it for viruses, check that it is not spam, and all sorts of other things, before finally
storing it in Bob’s mailbox. [Link] will probably also send Bob a notification stating that he
has received a new e-mail, so Bob will be inclined to go read it. While there are many ways he
could do so. We will assume that Bob reads his e-mail through a Web Browser like Chrome, Safari,
Firefox, or Internet Explorer by going to [Link] and logging in.
When Bob types this into his browser’s address bar and presses Enter, a lot of things happen in
very quick succession. First, a DNS lookup is performed for the domain name [Link]. Second,
a connection is established to [Link] using TCP. Third, his browser sends a request over that
connection using the Hypertext Transfer Protocol, or HTTP. “But wait!”, I hear you cry, “won’t
that connection reach the mail server that is running at [Link]?”.
To address this question, we need to talk a bit more about TCP. In addition to providing reliable
connections, TCP also provides what is known as application multiplexing. That is, multiple
servers can run on a single machine, and remote clients can choose which one they wish to connect
to by specifying a port. Many of these port numbers are well-known; for example, the port for
sending mail is port number 25, and the port for accessing web sites is port 80. Some of you may
have seen this in the address bar of your browser: when the domain name is followed by a colon,
and then a number ([Link] this tells the browser to use that port instead of the
default port (which is 80 for HTTP).
Bob’s browser has now established a connection to the web server running on [Link], and is
ready to request the login page. For this, it uses HTTP, which looks somewhat similar to the IMF
format we used for Alice’s e-mail. It consist of three parts: an “action” line (e.g. GET /login),
several lines of key/value pairs (e.g. User-Agent: Mozilla/Firefox, Host: [Link]), and then any
data that Bob wants to send to the web server (e.g. his login information).
22
GET /login HTTP/1.1
Host: [Link]
the [Link] web server will reply with an HTML document. HTML (or HyperText Markup
Language) is akin to a programming language, and lets developers of web pages construct pages
that are more than simply plain text. HTML lets the developer include images, links, and videos,
as well as style the contents of the page by changing colors, font sizes, etc. Modern HTML sites
also use more sophisticated tools for styling and altering their pages on the fly. For instance, you
may have seen that on many websites, clicking a link or doing a search will not cause the page to
reload, but instead the results will pleasantly (and quickly) animate into the page you are currently
on. This is done using the web programming language JavaScript.
Given this HTML document (along with any styles or scripts), the browser will render the login
page to Bob, showing him a login form. When Bob “submits” this form, another HTTP request
will be sent:
username=bob@[Link]&password=bob_is_super_cool!
Notice that this request is no longer a GET request, but POST, which tells the web server that Bob
is sending it some data that it should consider. In this case, the data in the request is Bob’s username
and password, which the web server will use to authenticate Bob. If Bob’s credentials were valid,
the server will respond with another HTML document, this time showing Bob his inbox. It will
also include what is known as a cookie. A cookie is an identifier that Bob’s web browser will pass
with every subsequent HTTP request to [Link], to prove that he is still Bob. For example, if
Bob later goes to [Link] his browser might send something like:
23
The web server will recognize this token, and allow Bob access to his inbox without requiring him
to log in again. The astute reader may notice that this cookie allows the web site to “track” Bob as
he navigates through the site. This might not be such a problem in this case, since Bob really does
want to be associated with [Link], but for third-party advertisement sites, this becomes a
problem. Since Bob’s browser will always include the cookie it has for a particular domain name,
if two web sites use the same advertisement provider (say, [Link]), then [Link] can see that
Bob has visited both of these sites. The same goes for Facebook’s like buttons that are distributed
throughout the web today; they are all loaded from [Link], and so Facebook gets to see all
the sites you visit that have a Facebook Like button on them. Many browser now try to block this
information from leaking, and this was the motivation for the infamous EU “Cookie Law”, but it
can be hard to fix this problem in its entirety without breaking many web pages that rely on this
behavior.
When Bob’s web browser shows him his inbox, he can read Alice’s e-mail simply by sending
another HTTP request for it. The web server will, entirely unbeknownst to Bob, unwrap the IMF
envelope, and format the e-mail nicely using HTML, before sending it back to his web browser.
Finally, Bob can read Alice’s e-mail. Yay!
So, now we’re done, right? Well, not quite. There are still some loose ends to tie up. First, you
may have questioned how a single machine can be responsible for all of [Link]’s e-mail, and
you would be entirely correct to do so. In practice, DNS will often return multiple addresses when
a particular domain name is looked up, and the web browser simply chooses one of them at
random. There are also other computers, known as load-balancers, that will take all the inbound
traffic for a particular address, and distribute it to many many servers that it is responsible for.
[Link] uses both of these to ensure that its service almost never becomes unavailable to users.
A single server can also have multiple domain names associated with it (e.g. the IP address
[Link] might handle both [Link] and [Link]), and this is the reason many
protocols (like HTTP) include a Host field identifying which domain name the client is expecting
to talk to.
Another observation you may have made is that addresses on the web are increasingly prefixed
with [Link] and not just [Link] The s stands for “Secure”, and implies that a protocol known as
24
Transport Layer Security, or TLS is in use. TLS attempts to authenticate one or both parts of a
network connection (i.e. so Bob can know that he is talking to the “real” [Link]), as well as
hide the information being exchanged from snooping. TLS is mostly transparent to users, as the
browser runs it automatically just below HTTP, where it silently encrypts all the text before it is
sent on the network between the server and the client (and vice-versa). In fact, TLS is so
transparent and versatile that it can also be used for the mail exchange protocol we discussed when
Alice was sending her e-mail to [Link]. A discussion about TLS is outside the scope of this
post, but suffice to say that correctly using TLS is quite hard, and that it relies on trusting some
fairly large security organizations.
The final piece of the puzzle is what really happens to get packets from one machine’s gateway to
another’s. Clearly, every pair of gateways cannot be connected by a single cable as we assumed
above, so something more complicated must be going on. In fact, the core of the Internet is so
complex that it cannot be readily explained in a post such as this. We will instead give a simplified
summary.
The core of the Internet has many layers, or tiers. Smaller Internet Service Providers are usually
in the lowest layer, “Tier 3”. Tier 3 providers only connect together a small number of users, and
cannot provide connectivity to any machine that is not on their network. To connect their users
with the Internet, Tier 3 providers will establish a contract with a Tier 2 provider to lease access
to the Internet from them. When a Tier 3 provider receives traffic that is not destined for any of its
users, it will simply forward it to its Tier 2 provider.
Tier 2 providers are often larger, and will have peering agreements with a number of other Tier 2
providers. For example, many Tier 2 providers may want to peer with Netflix’s network so they
can provide better connectivity for their users. Peering simply means that some money exchanges
hands, and a dedicated network link is established between two Tier 2 providers. However, a Tier
2 provider also does not have direct connectivity to all the machines on the Internet; Tier 2
providers are usually regional, and have only users in, say, the continental United States. Just like
Tier 3 providers, all Tier 2 traffic that is not destined for their own users needs to go further up the
chain. As you might have guessed, the traffic goes to a Tier 1 provider that the Tier 2 provider is
paying for access to the rest of the Internet.
25
Tier 1 providers are international entities that provide connectivity between countries or
continents, and that are connected to a very large number of users (or Tier 2 providers). However,
even Tier 1 providers do not have connections to every machine wanting to be accessible on the
Internet. Instead, the Tier 1 providers all peer with one another, often without any money
exchanging hands. This works simply because all the Tier 1 providers bring a large number of both
users and traffic to the table, and they all want to provide global connectivity, so it is in everyone’s
best interest that they cooperate. That said, there have been instances of so-called “peering wars”,
where Tier 1 providers disagree, and end up severing the connection between different parts of the
Internet. When this happens, huge swaths of users lose connectivity to certain parts of the Internet.
So, how does this tie together with Alice’s e-mail for Bob? When the packets destined for
[Link] reach Alice’s gateway, it will forward them to Alice’s ISP. Her ISP will first check if
[Link] is also a customer of the same ISP, and if so, it will send the packet directly to
[Link]’s gateway (like we assumed initially). If [Link] is not a subscriber of the same ISP,
the packets are forwarded to the ISP’s Tier 2 provider. The Tier 2 provider will check all its
customers’ and peers’ networks to see if [Link] is to be found there, and if so, forward the
packets there. If [Link] is not on any of those networks, the packets are forwarded further up
the chain to a Tier 1 provider. The Tier 1 provider will check which of its Tier 1 peers are ultimately
responsible for [Link], and forward the packet to them, From there, the packets will descend
the pyramid until they reach [Link]’s ISP, which will finally forward the packets to
[Link]’s gateway.
26
MODULE FIVE
WEB FRAMEWORKS IN PYTHON
1. Learning Objectives
Python can be used to build server-side web applications. While a web framework is not required
to build web apps, it's rare that developers would not use existing open-source libraries to speed
up their progress in getting their application working.
Python is not used in a web browser. The language executed in browsers such as Chrome, Firefox
and Internet Explorer is JavaScript. Projects such as pyjs can compile from Python to JavaScript.
However, most Python developers write their web applications using a combination of Python and
JavaScript. Python is executed on the server side while JavaScript is downloaded to the client and
run by the web browser.
A web framework is a code library that makes web development faster and easier by providing
common patterns for building reliable, scalable and maintainable web applications.
27
Web frameworks are software toolkits designed to streamline and accelerate the development of
web applications, web services, and APIs by providing pre-written code libraries, standard
architectural patterns, and built-in utility features. Instead of writing routine code from scratch,
developers leverage frameworks to handle repetitive tasks like URL routing, database interactions,
session management, and authentication safety.
After the early 2000s, professional web development projects always use an existing web
framework except in very unusual situations.
Frameworks make it easier to reuse code for common HTTP operations and to structure projects
so other developers with knowledge of the framework can quickly build and maintain the
application.
1. URL routing
2. Input form handling and validation
3. HTML, XML, JSON, and other output formats with a templating engine
4. Database connection configuration and persistent data manipulation through an object-
relational mapper (ORM)
5. Web security against Cross-site request forgery (CSRF), SQL Injection, Cross-site
Scripting (XSS) and other common malicious attacks
6. Session storage and retrieval
Not all web frameworks include code for all of the above functionality. Frameworks fall on the
spectrum from executing a single use case to providing every known web framework feature to
every developer. Some frameworks take the "batteries-included" approach where everything
possible comes bundled with the framework while others have a minimal core package that is
amenable to extensions provided by other packages.
28
For example, the Django web application framework includes the Django ORM layer that allows
a developer to write relational database read, write, query, and delete operations in Python code
rather than SQL. However, Django's ORM cannot work without significant modification on non-
relational (NoSQL) databases such as MongoDB or Cassandra.
Some other web frameworks such as Flask and Pyramid are easier to use with non-relational
databases by incorporating external Python libraries. There is a spectrum between minimal
functionality with easy extensibility on one end and including everything in the framework with
tight integration on the other end.
Whether or not you use a web framework in your project depends on your experience with web
development and what you're trying to accomplish. If you are a beginner programmer and just
want to work on a web application as a learning project then a framework can help you understand
the concepts listed above, such as URL routing, data manipulation and authentication that are
common to the majority of web applications.
On the other hand, if you're an experienced programmer with significant web development
experience you may feel like the existing frameworks do not match your project's requirements.
In that case, you can mix and match open-source libraries such as Werkzeug for WSGI plumbing
with your own code to create your own framework. There's still plenty of room in the Python
ecosystem for new frameworks to satisfy the needs of web developers that are unmet by Django,
Flask, Pyramid, Bottle and many others.
In short, whether or not you need to use a web framework to build a web application depends on
your experience and what you're trying to accomplish. Using a web framework to build a web
application certainly isn't required, but it'll make most developers' lives easier in many cases.
A web framework is a collection of software tools, libraries, and predefined structures that helps
developers build, deploy, and maintain websites, web applications, and web APIs more
efficiently.
29
Instead of writing every part of a web application from scratch, a web framework provides ready-
made features for common web development tasks, such as:
Example
Suppose you want to develop a Student Management System. Without a web framework, you
would have to manually implement much of the infrastructure for handling web requests, routing
URLs, managing sessions, and connecting application logic to the web server.
With a framework such as Flask or Django, many of these functions are already available. The
programmer can therefore concentrate more on the specific functionality of the application.
Simple Architecture
User/Client
│
│ HTTP Request
▼
Web Framework
│
├── URL Routing
├── Application Logic
├── Authentication
30
├── Database Access
└── Template Rendering
│
▼
Web Server
│
│ HTTP Response
▼
User/Client
31
5.1.2 Advantages of Web Frameworks
Python has several web frameworks. The most popular include Flask, Django, FastAPI,
Pyramid, and Tornado.
5.2.1 Flask
Flask is a lightweight web framework used to build web applications and APIs. It follows a
minimal design and provides core features like routing, request handling and template rendering
while allowing developers to add extensions as needed. It is widely used for building small to
medium web applications due to its simplicity and flexibility. Unlike Django, Flask provides a
smaller core and allows developers to add only the components they need. Flask is based on the
Werkzeug WSGI toolkit and Jinja2 template engine. Both are Pocco projects.
Features of Flask:
• Built-in Development Server: Allows to run and test applications locally without extra
setup.
• Template Engine (Jinja2): Helps create dynamic HTML pages with reusable templates.
32
• Extension Support: Integrates with extensions like Flask-SQLAlchemy for added
functionality.
• RESTful Request Handling: Provides tools to handle HTTP methods like GET, POST,
PUT and DELETE.
• Debug Mode: Automatically reloads the server and shows errors during development.
Suitable For
WSGI
Web Server Gateway Interface (WSGI) has been adopted as a standard for Python web application
development. WSGI is a specification for a universal interface between the web server and the
web applications.
Werkzeug
It is a WSGI toolkit, which implements requests, response objects, and other utility functions. This
enables building a web framework on top of it. The Flask framework uses Werkzeug as one of its
bases.
Jinja2
Jinja2 is a popular templating engine for Python. A web templating system combines a template
with a certain data source to render dynamic web pages.
33
Flask is often referred to as a micro framework. It aims to keep the core of an application simple
yet extensible. Flask does not have built-in abstraction layer for database handling, nor does it have
form a validation support. Instead, Flask supports the extensions to add such functionality to the
application.
For an Advanced Python Programming course, Flask is an excellent framework for practical
teaching because students can easily understand the fundamental concepts of web
application development.
The next step is to install Flask, but before I go into that I want to tell you about the best
practices associated with installing Python packages. In Python, packages such as Flask
are available in a public repository, from where anybody can download them and install
them. The official Python package repository is called PyPI, which stands for Python
Package Index (some people also refer to this repository as the “cheese shop”). Installing
a package from PyPI is very simple, because Python comes with a tool called pip that does
this work (in Python 2.7 pip does not come bundled with Python and needs to be installed
separately).
Interestingly, this method of installing packages will not work in most cases. If your Python
interpreter was installed globally for all the users of your computer, chances are your
regular user account is not going to have permission to make modifications to it, so the
only way to make the command above work is to run it from an administrator account. But
even without that complication, consider what happens when you install a package as
34
above. The pip tool is going to download the package from PyPI, and then add it to your
Python installation.
From that point on, every Python script that you have on your system will have access to
this package. Imagine a situation where you have completed a web application using
version 0.11 of Flask, which was the most current version of Flask when you started, but
now has been superseeded by version 0.12. You now want to start a second application, for
which you’d like to use the 0.12 version, but if you replace the 0.11 version that you have
installed you risk breaking your older application. Do you see the problem? It would be
ideal if it was possible to install Flask 0.11 to be used by your old application, and also
install Flask 0.12 for your new one.
Virtual environments
Use a virtual environment to manage the dependencies for your project, both in development and
in production.
What problem does a virtual environment solve? The more Python projects you have, the more
likely it is that you need to work with different versions of Python libraries, or even Python itself.
Newer versions of libraries for one project can break compatibility in another project.
Virtual environments are independent groups of Python libraries, one for each project. Packages
installed for one project will not affect other projects or the operating system’s packages.
35
Python comes bundled with the venv module to create virtual environments.
Create an environment
> .venv\Scripts\activate
Your shell prompt will change to show the name of the activated environment.
Before installing Flask, ensure that Python is properly installed on your system. Run the
following command in the Command Prompt:
python --version
Open the Command Prompt and run the following command to install Flask with its required
dependencies:
36
Let’s start by creating a directory where the project will live. Let’s call this directory microblog,
since that is the name of the supposed application:
$ mkdir microblog
$ cd microblog
If you are using a Python 3 version, virtual environment support is included in it, so all you need
to do to create one is this:
With this command, I’m asking Python to run the venv package, which creates a virtual
environment named venv. The first venv in the command is the name of the Python virtual
environment package, and the second is the virtual environment name that I’m going to use for
this particular environment. If you find this confusing, you can replace the second venv with a
different name that you want to assign to your virtual environment. In general, I create my virtual
environments with the name venv in the project directory, so whenever I cd into a project I find its
corresponding virtual environment.
Note that in some operating systems you may need to use python instead of python3 in the
command above. Some installations use python for Python 2.x releases and python3 for the 3.x
releases, while others map python to the 3.x releases. After the command completes, you are going
to have a directory named venv where the virtual environment files are stored.
If you are using any version of Python older than 3.4 (and that includes the 2.7 release), virtual
environments are not supported natively. For those versions of Python, you need to download and
install a third-party tool called virtualenv before you can create virtual environments. Once
virtualenv is installed, you can create a virtual environment with the following command:
$ virtualenv venv
37
Regardless of the method you used to create it, you should have your virtual environment created.
Now you have to tell the system that you want to use it, and you do that by activating it. To activate
your brand-new virtual environment, you use the following command:
If you are using Linux or macOS, run the following command to activate your virtual
environment:
$ source venv/bin/activate
(venv) $ _
If you are using a Microsoft Windows command prompt window, the activation command is
slightly different:
$ venv\Scripts\activate
Or
(venv) $ _
When you activate a virtual environment, the configuration of your terminal session is modified
so that the Python interpreter stored inside it is the one that is invoked when you type python. Also,
the terminal prompt is modified to include the name of the activated virtual environment. The
changes made to your terminal session are all temporary and private to that session, so they will
not persist when you close the terminal window. If you work with multiple terminal windows open
at the same time, it is perfectly fine to have different virtual environments activated on each one.
Now that you have a virtual environment created and activated, you can finally install Flask in it:
38
>>> _
If this statement does not give you any errors you can congratulate
39
Collecting jinja2>=3.1.2 (from flask)
Downloading [Link] (134 kB)
---------------------------------------- 134.9/134.9 kB 890.4 kB/s eta 0:00:00
Collecting markupsafe>=2.1.1 (from flask)
Downloading markupsafe-3.0.3-cp311-cp311-win_amd64.whl (15 kB)
Collecting werkzeug>=3.1.0 (from flask)
Downloading [Link] (226 kB)
---------------------------------------- 226.5/226.5 kB 812.9 kB/s eta 0:00:00
Collecting colorama (from click>=8.1.3->flask)
Downloading [Link] (25 kB)
Installing collected packages: markupsafe, itsdangerous, colorama, blinker, werkzeug, jinja2, click, flask
Successfully installed blinker-1.9.0 click-8.4.2 colorama-0.4.6 flask-3.1.3 itsdangerous-2.2.0 jinja2-3.1.6
markupsafe-3.0.3 werkzeug-3.1.8
Installation in Linux
Step 1: Check Python Installation
Run the following command in the Terminal to verify if Python is install in your system or not:
python3 --version
Run the following command in the terminal to install Flask with its required dependencies:
40
Terminal Screenshot
Open the Python shell and try importing Flask to verify if Flask is installed correctly:
python3
>>> import flask
To r
5.2.2 Django
Django is a powerful, open-source, full-stack Python web framework designed for developing
large and complex web applications.
Django is a high-level Python web framework that enables rapid development of secure and
maintainable websites. Built by experienced developers, Django takes care of much of the hassle
of web development, so you can focus on writing your app without needing to reinvent the
wheel. It is free and open source, has a thriving and active community, great documentation, and
many options for free and paid-for support.
41
Django helps you write software that is:
Complete
Django follows the "Batteries included" philosophy and provides almost everything
developers might want to do "out of the box". Because everything you need is part of the
one "product", it all works seamlessly together, follows consistent design principles, and
has extensive and up-to-date documentation.
Versatile
Django can be (and has been) used to build almost any type of website — from content
management systems and wikis, through to social networks and news sites. It can work
with any client-side framework, and can deliver content in almost any format (including
HTML, RSS feeds, JSON, and XML).
Internally, while it provides choices for almost any functionality you might want (e.g.,
several popular databases, templating engines, etc.), it can also be extended to use other
components if needed.
Secure
Django helps developers avoid many common security mistakes by providing a framework
that has been engineered to "do the right things" to protect the website automatically. For
example, Django provides a secure way to manage user accounts and passwords, avoiding
common mistakes like putting session information in cookies where it is vulnerable
(instead cookies just contain a key, and the actual data is stored in the database) or directly
storing passwords rather than a password hash.
42
Django enables protection against many vulnerabilities by default, including SQL
injection, cross-site scripting, cross-site request forgery and clickjacking.
Scalable
Maintainable
Django code is written using design principles and patterns that encourage the creation of
maintainable and reusable code. In particular, it makes use of the Don't Repeat Yourself
(DRY) principle so there is no unnecessary duplication, reducing the amount of code.
Django also promotes the grouping of related functionality into reusable "applications"
and, at a lower level, groups related code into modules (along the lines of the Model View
Controller (MVC) pattern).
Portable
Django is written in Python, which runs on many platforms. That means that you are not
tied to any particular server platform, and can run your applications on many flavors of
Linux, Windows, and macOS. Furthermore, Django is well-supported by many web
hosting providers, who often provide specific infrastructure and documentation for hosting
Django sites.
ORIGIN OF DJANGO
Django was initially developed between 2003 and 2005 by a web team who were responsible for
creating and maintaining newspaper websites. After creating a number of sites, the team began to
factor out and reuse lots of common code and design patterns. This common code evolved into a
43
generic web development framework, which was open-sourced as the "Django" project in July
2005.
Django has continued to grow and improve, from its first milestone release (1.0) in September
2008 through to the version 5.0 in late 2023. Each release has added new functionality and bug
fixes, ranging from support for new types of databases, template engines, and caching, through to
the addition of "generic" view functions and classes (which reduce the amount of code that
developers have to write for a number of programming tasks).
Django is now a thriving, collaborative open source project, with many thousands of users and
contributors. While it does still have some features that reflect its origin, Django has evolved into
a versatile framework that is capable of developing any type of website.
MVT stands for Model, View, and Template. It is designed to separate the concerns of data
(model), logic (view), and presentation (template), making it easier for developers to manage and
scale web applications. Think of it as a clear division of labour for your application, where each
component has a specific job.
Model
In Django, a model is a Python class that defines the structure and behavior of your application’s
data. Each model typically maps to a single database table, where the class attributes define the
table’s columns while every instance of the class represents a row in that table.
The model layer communicates with the database through Django’s Object-Relational Mapper
(ORM). The ORM allows you to interact with data as Python objects rather than writing raw SQL
queries. This abstraction makes it easier to create, read, update, and delete records while keeping
your code clean, efficient, and database-agnostic.
44
View
A View in Django is a Python function or class that serves as the logic layer of your application. It
acts as the bridge between the model, which manages your data, and the template, which defines
how that data is presented to the user. When an HTTP request comes in, the view is responsible for
processing it — this may involve validating input, retrieving or updating data from the database,
and applying any necessary business logic. Once the work is done, the view prepares a response,
often by passing the data to a template, which then generates the final HTML page sent back to the
user’s browser.
Template
A template is the presentation layer of your application. Templates are usually HTML files
enhanced with Django’s template language, which allows you to insert dynamic content, loop
through data, and add conditional logic in a clean and readable way. The template’s main
responsibility is to take the data provided by the view and render it into a format that can be
displayed in the user’s browser — most often as an HTML page, but it could also be XML, JSON,
or other formats depending on the application. By separating presentation from business logic,
templates make it easier to design, customize, and maintain the user interface without interfering
with the underlying data or logic.
Here is the sequence of events when a user interacts with a Django application:
45
1. Request: A user’s browser sends an HTTP request to a URL on your site.
2. URL Routing: Django’s URL dispatcher, defined in [Link], matches the incoming
URL to a specific View.
3. View Invocation: The matched View receives the request. It can examine request data
(like GET or POST parameters) and then uses the Model to perform database
operations.
4. Model Operations: The Model’s ORM provides an abstraction layer, allowing the
View to work with database records as Python objects. For example,
a filter() or save() query is executed here.
5. Template Selection and Rendering: After the View has the necessary data, it passes
that data to a Template. The template uses Django’s template language to render the
final HTML, inserting dynamic content.
46
Model–View–Template. It’s just a smart way to organize your code so everything has its place
and job Model: Think of this as the part that handles your data. It talks to the database and knows
what your app should store—like menu items, orders, users, etc. It’s the brain behind the scenes.
View: This is where your app’s logic lives. When someone visits your site or clicks a button, the
View decides what to do. It grabs data from the Model and sends it to the right place. You can
think of it as the decision-maker.
Template: This is what the user actually sees—HTML pages that look nice and show the right
info. Templates take the data from the View and display it in a clean, friendly way. So when
someone uses your Django app, the View handles their request, the Model gets the data, and the
Template shows it on the screen. All three work together to make the app run smoothly.
Key Features
47
• Template engine
• Form handling
• Security features
• Database support
Suitable For
• University portals
• E-commerce systems
• Content management systems
• Large enterprise applications
• Social networking applications
In a traditional data-driven website, a web application waits for HTTP requests from the web
browser (or other client). When a request is received the application works out what is needed
based on the URL and possibly information in POST data or GET data. Depending on what is
required it may then read or write information from a database or perform other tasks required to
satisfy the request. The application will then return a response to the web browser, often
dynamically creating an HTML page for the browser to display by inserting the retrieved data into
placeholders in an HTML template.
Django web applications typically group the code that handles each of these steps into separate
files:
48
• URLs: While it is possible to process requests from every single URL via a single function,
it is much more maintainable to write a separate view function to handle each resource. A
URL mapper is used to redirect HTTP requests to the appropriate view based on the request
URL. The URL mapper can also match particular patterns of strings or digits that appear
in a URL and pass these to a view function as data.
• View: A view is a request handler function, which receives HTTP requests and returns
HTTP responses. Views access the data needed to satisfy requests via models, and delegate
the formatting of the response to templates.
• Models: Models are Python objects that define the structure of an application's data, and
provide mechanisms to manage (add, modify, delete) and query records in the database.
• Templates: A template is a text file defining the structure or layout of a file (such as an
HTML page), with placeholders used to represent actual content. A view can dynamically
create an HTML page using an HTML template, populating it with data from a model. A
template can be used to define the structure of any type of file; it doesn't have to be HTML!
49
Note: Django refers to this organization as the "Model View Template (MVT)" architecture. It has
many similarities to the more familiar Model View Controller architecture.
The sections below will give you an idea of what these main parts of a Django app look like
(we'll go into more detail later on in the course, once we've set up a development environment).
A URL mapper is typically stored in a file named [Link]. In the example below, the mapper
(urlpatterns) defines a list of mappings between routes (specific URL patterns) and
corresponding view functions. If an HTTP Request is received that has a URL matching a specified
pattern, then the associated view function will be called and passed the request.
python
urlpatterns = [
path('admin/', [Link]),
path('book/<int:id>/', views.book_detail, name='book_detail'),
path('catalog/', include('[Link]')),
re_path(r'^([0-9]+)/$', [Link]),
]
The urlpatterns object is a list of path() and/or re_path() functions (Python lists are defined
using square brackets, where items are separated by commas and may have an optional trailing
comma. For example: [item1, item2, item3,]).
The first argument to both methods is a route (pattern) that will be matched. The path() method
uses angle brackets to define parts of a URL that will be captured and passed through to the view
function as named arguments. The re_path() function uses a flexible pattern matching approach
known as a regular expression. We'll talk about these in a later article!
The second argument is another function that will be called when the pattern is matched. The
notation views.book_detail indicates that the function is called book_detail() and can be
found in a module called views (i.e., inside a file named [Link])
50
Handling the request ([Link])
Views are the heart of the web application, receiving HTTP requests from web clients and
returning HTTP responses. In between, they marshal the other resources of the framework to
access databases, render templates, etc.
The example below shows a minimal view function index(), which could have been called by
our URL mapper in the previous section. Like all view functions it receives an HttpRequest object
as a parameter (request) and returns an HttpResponse object. In this case we don't do anything
with the request, and our response returns a hard-coded string. We'll show you a request that does
something more interesting in a later section.
python
# filename: [Link] (Django view functions)
def index(request):
# Get an HttpRequest - the request parameter
# perform operations using information from the request.
# Return HttpResponse
return HttpResponse('Hello from Django!')
• Python modules are "libraries" of functions, stored in separate files, that we might want
to use in our code. Here we import just the HttpResponse object from the
[Link] module so that we can use it in our view: from [Link]
import HttpResponse. There are other ways of importing some or all objects from
a module.
• Functions are declared using the def keyword as shown above, with named parameters
listed in parentheses after the name of the function; the whole line ends in a colon. Note
how the next lines are all indented. The indentation is important, as it specifies that the
lines of code are inside that particular block (mandatory indentation is a key feature of
Python, and is one reason that Python code is so easy to read).
51
Defining data models ([Link])
Django web applications manage and query data through Python objects referred to as models.
Models define the structure of stored data, including the field types and possibly also their
maximum size, default values, selection list options, help text for documentation, label text for
forms, etc. The definition of the model is independent of the underlying database — you can
choose one of several as part of your project settings. Once you've chosen what database you want
to use, you don't need to talk to it directly at all — you just write your model structure and other
code, and Django handles all the "dirty work" of communicating with the database for you.
The code snippet below shows a very simple Django model for a Team object. The Team class is
derived from the Django class [Link]. It defines the team name and team level as character
fields and specifies a maximum number of characters to be stored for each record. The team_level
can be one of several values, so we define it as a choice field and provide a mapping between
choices to be displayed and data to be stored, along with a default value.
python
# filename: [Link]
class Team([Link]):
team_name = [Link](max_length=40)
TEAM_LEVELS = (
('U09', 'Under 09s'),
('U10', 'Under 10s'),
('U11', 'Under 11s'),
# …
# list other team levels
)
team_level = [Link](max_length=3, choices=TEAM_LEVELS,
default='U11')
52
to be shared. In Python we use the keyword class to define the "blueprint" for an object. We can
create multiple specific instances of the type of object based on the model in the class.
So for example, here we have a Team class, which derives from the Model class. This means it is a
model, and will contain all the methods of a model, but we can also give it specialized features of
its own too. In our model we define the fields our database will need to store our data, giving them
specific names. Django uses these definitions, including the field names, to create the underlying
database.
The Django model provides a simple query API for searching the associated database. This can
match against a number of fields at a time using different criteria (e.g., exact, case-insensitive,
greater than, etc.), and can support complex statements (for example, you can specify a search on
U11 teams that have a team name that starts with "Fr" or ends with "al").
The code snippet shows a view function (resource handler) for displaying all of our U09 teams.
The list_teams = [Link](team_level__exact="U09") line shows how we
can use the model query API to filter for all records where the team_level field has exactly the
text U09 (note how this criteria is passed to the filter() function as an argument, with the field
name and match type separated by a double underscore: team_level__exact).
python
## filename: [Link]
def index(request):
list_teams = [Link](team_level__exact="U09")
context = {'youngest_teams': list_teams}
return render(request, '/best/[Link]', context)
This function uses the render() function to create the HttpResponse that is sent back to the
browser. This function is a shortcut; it creates an HTML file by combining a specified HTML
template and some data to insert in the template (provided in the variable named context). In the
next section we show how the template has the data inserted in it to create the HTML.
53
Rendering data (HTML templates)
Template systems allow you to specify the structure of an output document, using placeholders for
data that will be filled in when a page is generated. Templates are often used to create HTML, but
can also create other types of document. Django supports both its native templating system and
another popular Python library called Jinja2 out of the box (it can also be made to support other
systems if needed).
The code snippet shows what the HTML template called by the render() function in the previous
section might look like. This template has been written under the assumption that it will have
access to a list variable called youngest_teams when it is rendered (this is contained in the
context variable inside the render() function above). Inside the HTML skeleton we have an
expression that first checks if the youngest_teams variable exists, and then iterates it in a for
loop. On each iteration the template displays each team's team_name value in an <li> element.
django
## filename: best/templates/best/[Link]
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Home page</title>
</head>
<body>
{% if youngest_teams %}
<ul>
{% for team in youngest_teams %}
<li>{{ team.team_name }}</li>
{% endfor %}
</ul>
{% else %}
<p>No teams are available.</p>
{% endif %}
</body>
</html>
54
Structure of Django Project
A newly created Django project contains several files and directories that work together to
implement the MVT architecture. Inside the project folder, the following major files are
included:
55
• [Link]: Contains all configuration settings for the project, including installed
apps, middleware, databases, templates, static files and security options that define
the project’s behavior and environment.
• [Link]: A URL mapper is typically stored in a file named [Link]. It defines the
URL routing configuration for the project, mapping URL patterns to corresponding
views or other URL files to direct incoming requests to the appropriate part of the
application.
• [Link]: Entry point for WSGI-compatible servers. Used for serving Django
applications in traditional synchronous environments.
5.2.3 FastAPI
FastAPI is a modern Python web framework primarily designed for building high-performance
APIs. It makes extensive use of Python type hints and provides automatic API documentation.
Key Features
• High performance
• Automatic API documentation
• Data validation
• Type hints
• Asynchronous programming support
• REST API development
Suitable For
• RESTful APIs
• Microservices
• Machine learning model APIs
• AI application backends
56
• High-performance applications
5.4 Pyramid
Pyramid is a flexible Python web framework that can be used to develop applications ranging
from small projects to large systems.
It allows developers to choose the components and architecture that best suit their application.
Suitable For
5.5 Tornado
Tornado is a Python web framework and asynchronous networking library designed for
applications that require high concurrency and real-time communication.
Suitable For
• Real-time applications
• WebSockets
• Long-lived connections
• High-concurrency applications
Summary Comparison
Framework Type Main Strength Typical Application
57
Framework Type Main Strength Typical Application
APIs, AI and ML
FastAPI API framework High-performance APIs
backends
Asynchronous
Tornado Real-time and high concurrency Real-time applications
framework
58
MODULE SIX
A Minimal Application
app = Flask(__name__)
@[Link]("/")
def hello_world():
return "<p>Hello, World!</p>"
1. First, we imported the Flask class. An instance of this class will be our WSGI (Web
Server Gateway Interface) application.
WSGI (Web Server Gateway Interface) is a standard rule set that connects Python web
apps to web servers, using a simple callable function with environ and start_response
parameters. It lets different frameworks like Flask or Django run on servers like Gunicorn
or Apache.
2. Next, we create an instance of this class. The first argument is the name of the application’s
module or package. __name__ is a convenient shortcut for this that is appropriate for
most cases. This is needed so that Flask knows where to look for resources such as
templates and static files.
3. We then use the route () decorator to tell Flask what URL should trigger our function.
4. The function returns the message we want to display in the user’s browser. The default
content type is HTML, so HTML in the string will be rendered by the browser.
59
Save it as [Link] or something similar. Make sure to not call your application [Link]
because this would conflict with Flask itself.
To run the application, use the flask command or python -m flask. You need to tell the
Flask where your application is with the --app option.
A slightly more elaborate one that will give you a good base structure for writing larger
applications.
The application will exist in a package. In Python, a sub-directory that includes a __init__.py file
is considered a package, and can be imported. When you import a package, the __init__.py
executes and defines what symbols the package exposes to the outside world.
Let’s create a package called app, that will host the application. Make sure you are in the microblog
directory and then run the following command:
The __init__.py for the app package is going to contain the following
code:
60
app = Flask(__name__)
The script above simply creates the application object as an instance of class Flask imported from
the flask package. The __name__ variable passed to the Flask class is a Python predefined variable,
which is set to the name of the module in which it is used. Flask uses the location of the module
passed here as a starting point when it needs to load associated resources such as template files.
For all practical purposes, passing __name__ is almost always going to configure Flask in the
correct way. The application then imports the routes module, which doesn’t exist yet. One aspect
that may seem confusing at first is that there are two entities named app. The app package is defined
by the app directory and the __init__.py script, and is referenced in the from app import routes
statement. The app variable is defined as an instance of class Flask in the __init__.py script, which
makes it a member of the app package.
Another peculiarity is that the routes module is imported at the bottom and not at the top of the
script as it is always done. The bottom import is a workaround to circular imports, a common
problem with Flask applications. You are going to see that the routes module needs to import the
app variable defined in this script, so putting one of the reciprocal imports at the bottom avoids the
error that results from the mutual references between these two files.
So, what goes in the routes module? The routes are the different URLs that the application
implements. In Flask, handlers for the application routes are written as Python functions, called
view functions. View functions are mapped to one or more route URLs so that Flask knows what
logic to execute when a client requests a given URL.
Here is the first view function for this application, which you need to write in a new module named
app/[Link]:
@[Link]('/')
61
@[Link]('/index')
def index():
This view function is actually pretty simple, it just returns a greeting as a string. The two strange
@[Link] lines above the function are decorators, a unique feature of the Python language. A
decorator modifies the function that follows it. A common pattern with decorators is to use them
to register functions as callbacks for certain events. In this case, the @[Link] decorator creates
an association between the URL given as an argument and the function. In this example there are
two decorators, which associate the URLs / and /index to this function. This means that when a
web browser requests either of these two URLs, Flask is going to invoke this function and pass the
return value of it back to the browser as a response. If this does not make complete sense yet, it
will in a little bit when you run this application.
To complete the application, you need to have a Python script at the top-level that defines the Flask
application instance. Let’s call this script [Link], and define it as a single line that imports
the application instance:
Remember the two app entities? Here you can see both together in the same sentence. The Flask
application instance is called app and is a member of the app package. The from app import app
statement imports the app variable that is a member of the app package. If you find this confusing,
you can rename either the package or the variable to something else.
Just to make sure that you are doing everything correctly, below you can see a diagram of the
project structure so far:
62
microblog/
venv/
app/
__init__.py
[Link]
[Link]
Believe it or not, this first version of the application is now complete! Before running it, though,
Flask needs to be told how to import it, by setting the FLASK_APP environment variable:
If you are using the Microsoft Windows command prompt, use set instead of export in the
command above. Are you ready to be blown away? You can run your first web application, with
the following command:
After the server initializes it will wait for client connections. The output from flask run indicates
that the server is running on IP address [Link], which is always the address of your own
computer. This address is so common that is also has a simpler name that you may have seen
before: localhost. Network servers listen for connections on a specific port number. Applications
deployed on production web servers typically listen on port 443, or sometimes 80 if they do not
implement encryption, but access to these ports require administration rights. Since this application
is running in a development environment, Flask uses the freely available port 5000.
Now open up your web browser and enter the following URL in the address field:
63
[Link]
[Link]
Do you see the application route mappings in action? The first URL maps to /, while the second
maps to /index. Both routes are associated with the only view function in the application, so they
produce the same output, which is the string that the function returns.
If you enter any other URL, you will get an error, since only these two URLs are recognized by
the application.
When you are done playing with the server you can just press Ctrl-C to stop it. Congratulations,
you have completed the first big step to become a web developer!
64
I want to mention one more thing. Since environment variables aren’t remembered across terminal
sessions, you may find tedious to always have to set the FLASK_APP environment variable when
you open a new terminal window. Starting with version 1.0, Flask allows you to register
environment variables that you want to be automatically imported when you run the flask
command. To use this option you have to install the python-dotenv package:
Then you can just write the environment variable name and value in a .flaskenv file in the top-
level directory of the project:
FLASK_APP=[Link]
Doing this is optional. If you prefer to set the environment variable manually, that is perfectly fine,
as long as you always remember to do it.
To create a flask application firstly import a flask and then create a flask
instance after that create a default route using a decorator in python. Create
a function that returns a string that is displayed on the webpage. Start the
flask web app with debug mode on.
# import the Flask library
from flask import Flask
65
@[Link]('/')
def welcome():
return "Hello! Let us learn about importance of Exercise!"
# Start with flask web app, with debug as True,# only if this is the
starting page
if(__name__ == "__main__"):
[Link](debug=True)
Output:
Flask Application 3
In order to test Flask installation, type the following code in the editor as [Link]
@[Link]('/')
def hello_world():
return 'Hello World'
if __name__ == '__main__':
[Link]()
Importing flask module in the project is mandatory. An object of Flask class is our WSGI
application.
66
Flask constructor takes the name of current module (__name__) as argument.
The route() function of the Flask class is a decorator, which tells the application which URL
should call the associated function.
[Link](rule, options)
In the above example, / URL is bound with hello_world() function. Hence, when the home page
of web server is opened in browser, the output of this function will be rendered.
Finally the run() method of Flask class runs the application on the local development server.
host
1
Hostname to listen on. Defaults to [Link] (localhost). Set to [Link] to have server
available externally
port
2
Defaults to 5000
debug
3
Defaults to false. If set to true, provides a debug information
options
4
To be forwarded to underlying Werkzeug server.
Python [Link]
Open the above URL (localhost:5000) in the browser. Hello World message will be displayed
on it.
67
Debug mode
A Flask application is started by calling the run() method. However, while the application is
under development, it should be restarted manually for each change in the code. To avoid this
inconvenience, enable debug support. The server will then reload itself if the code changes. It
will also provide a useful debugger to track the errors if any, in the application.
The Debug mode is enabled by setting the debug property of the application object to True
before running or passing the debug parameter to the run() method.
[Link] = True
[Link]()
[Link](debug = True)
Flask Routing
Modern web frameworks use the routing technique to help a user remember application URLs. It
is useful to access the desired page directly without having to navigate from the home page.
The route() decorator in Flask is used to bind URL to a function. For example −
@[Link](/hello)
def hello_world():
return hello world
Here, URL /hello rule is bound to the hello_world() function. As a result, if a user visits
[Link] URL, the output of the hello_world() function will be rendered in the
browser.
The add_url_rule() function of an application object is also available to bind a URL with a
function as in the above example, route() is used.
def hello_world():
return hello world
app.add_url_rule(/, hello, hello_world)
68
Flask Variable Rules
It is possible to build a URL dynamically, by adding variable parts to the rule parameter. This
variable part is marked as <variable-name>. It is passed as a keyword argument to the function
with which the rule is associated.
In the following example, the rule parameter of route() decorator contains <name> variable part
attached to URL /hello. Hence, if the [Link] is entered as a
URL in the browser, TutorialPoint will be supplied to hello() function as argument.
@[Link]('/hello/<name>')
def hello_name(name):
return 'Hello %s!' % name
if __name__ == '__main__':
[Link](debug = True)
Save the above script as [Link] and run it from Python shell. Next, open the browser and enter
URL [Link]
Hello TutorialsPoint!
In addition to the default string variable part, rules can be constructed using the following
converters −
69
from flask import Flask
app = Flask(__name__)
@[Link]('/blog/<int:postID>')
def show_blog(postID):
return 'Blog Number %d' % postID
@[Link]('/rev/<float:revNo>')
def revision(revNo):
return 'Revision Number %f' % revNo
if __name__ == '__main__':
[Link]()
Run the above code from Python Shell. Visit the URL [Link] in the
browser.
The given number is used as argument to the show_blog() function. The browser displays the
following output −
Blog Number 11
The revision() function takes up the floating point number as argument. The following result
appears in the browser window −
The URL rules of Flask are based on Werkzeugs routing module. This ensures that the URLs
formed are unique and based on precedents laid down by Apache.
@[Link]('/flask')
def hello_flask():
return 'Hello Flask'
@[Link]('/python/')
def hello_python():
return 'Hello Python'
if __name__ == '__main__':
[Link]()
70
Both the rules appear similar but in the second rule, trailing slash (/) is used. As a result, it
becomes a canonical URL. Hence, using /python or /python/ returns the same output. However,
in case of the first rule, /flask/ URL results in 404 Not Found page.
@[Link]('/admin')
def hello_admin():
return 'Hello Admin'
@[Link]('/guest/<guest>')
def hello_guest(guest):
return 'Hello %s as Guest' % guest
@[Link]('/user/<name>')
def hello_user(name):
if name =='admin':
return redirect(url_for('hello_admin'))
else:
return redirect(url_for('hello_guest',guest = name))
if __name__ == '__main__':
[Link](debug = True)
The above script has a function user(name) which accepts a value to its argument from the
URL.
The User() function checks if an argument received matches admin or not. If it matches, the
application is redirected to the hello_admin() function using url_for(), otherwise to the
hello_guest() function passing the received argument as guest parameter to it.
71
Open the browser and enter URL as − [Link]
Hello Admin
By default, the Flask route responds to the GET requests. However, this preference can be
altered by providing methods argument to route() decorator.
72
In order to demonstrate the use of POST method in URL routing, first let us create an HTML
form and use the POST method to send form data to a URL.
<html>
<body>
<form action = "[Link] method = "post">
<p>Enter Name:</p>
<p><input type = "text" name = "nm" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
@[Link]('/success/<name>')
def success(name):
return 'welcome %s' % name
if __name__ == '__main__':
[Link](debug = True)
After the development server starts running, open [Link] in the browser, enter name in the
text field and click Submit.
73
Form data is POSTed to the URL in action clause of form tag.
[Link] is mapped to the login() function. Since the server has received data by
POST method, value of nm parameter obtained from the form data is obtained by −
user = [Link]['nm']
It is passed to /success URL as variable part. The browser displays a welcome message in the
window.
Change the method parameter to GET in [Link] and open it again in the browser. The data
received on server is by the GET method. The value of nm parameter is now obtained by −
User = [Link](nm)
74
Here, args is dictionary object containing a list of pairs of form parameter and its corresponding
value. The value corresponding to nm parameter is passed on to /success URL as before.
75
What is Flask Template?
A flask template is a template of a webpage that can be used by web developers to reduce the
hectic work of writing the code for each webpage of a website.
Flask template help us keep the logic of your application separate from the layout or presentation
of your web pages, in order to have a much better organized project structure.
Templates help achieve this separation between presentation and business logic. In Flask,
templates are written as separate files, stored in a templates folder that is inside the application
package. You could even hire a web designer to create a killer web site while you code the
application logic in Python.
The template files will be stored in the templates directory inside the flaskr package.
Templates are files that contain static data as well as placeholders for dynamic data. A template is
rendered with specific data to produce a final document. Flask uses the Jinja template library to
render templates.
In your application, you will use templates to render HTML which will display in the user’s
browser. In Flask, Jinja is configured to autoescape any data that is rendered in HTML templates.
This means that it’s safe to render user input; any characters they’ve entered that could mess with
the HTML, such as < and > will be escaped with safe values that look the same in the browser but
don’t cause unwanted effects.
Jinja looks and behaves mostly like Python. Special delimiters are used to distinguish Jinja syntax
from the static data in the template. Anything between {{ and }} is an expression that will be
output to the final document. {% and %} denotes a control flow statement like if and for. Unlike
Python, blocks are denoted by start and end tags rather than indentation since static text within a
block could change indentation.
76
For example, web developers can create a template that has headers like a navbar and footer
which is the same for all web pages. so instead of writing code for the header and footer of every
webpage, we can use that template.
render_template() method
The render_template() method, allows us to fetch the HTML files, and, pass them to the browser.
Hence, instead of rendering, raw string or inline HTML code, from the backend code to the
browser, we can have a separate HTML file, passed to the client.
So after making sure that you are in the microblog (if this is your project directory) directory,
create the directory where templates will be stored:
Step 1: Create a folder called 'templates', in the same directory level, as the Python code files.
Please note, that the folder name should be 'templates', and, any other name, would not allow for
the functionality to work properly.
(venv) $ mkdir app/templates
Step 2: Add all the HTML files of the application to the templates folder (for instance,
app/templates/[Link]).
Step 3: We will create [Link]', an HTML page, and add this file, to the templates folder.
The file, returns an index importance message, with some extra HTML code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Importance of Exercise</title>
</head>
<body>
77
<ul>Let us understand -
<li>Helps in Controlling Weight</li>
<li>Helps in Combating Diseases</li>
<li>Boosts Energy</li>
</ul>
</body>
</html>
Step 4: In Python code, we will first add, the import for the render_template() method.
Step 5: Now instead of returning a raw string, we will return the HTML file, present in the
templates folder, for the URL '[Link] In the method render_template(), we will
pass the HTML file name, to be rendered as an argument.
# import the Flask library
# import render_template method
from flask import Flask, render_template
78
# to be rendered, to the browser.
# The file should be present, in the 'templates' folder.
return render_template("[Link]")
Output:
The operation that converts a template into a complete HTML page is called rendering. To render
the template I had to import a function that comes with the Flask framework called
render_template(). This function takes a template filename and a variable list of template
arguments and returns the same template, but with all the placeholders in it replaced with actual
values.
The render_template() function invokes the Jinja2 template engine that comes bundled with the
Flask framework. Jinja2 substitutes {{... }} blocks with the corresponding values, given by the
arguments provided in the render_template() call.
79
Adding Dynamic Information with Templates
We can use, the render_template() method, to send dynamic data, to the front end(HTML file),
from the Python code. Similarly, variables, lists, and, so on can also be passed, from the Python
code. To do so, we will make use of 'Expressions' statements, in the HTML file. Let us add,
another view function, walking(), and pass variable values, of time and calories, to the front end
side. Add file '[Link]' in the templates folder. The Python code now looks as follows:
return render_template("[Link]")
80
Explanation: In the above code, we added a new view function, walking(), corresponding to
the route '/walk'. The view function renders the '[Link]' file (added in the templates
folder). Apart from that, we are passing the values of time and calories, to the HTML side, in
key-value pair format. The 'time' and 'calories' are keys, and, will be used on the HTML side, for
substituting appropriate values.
The HTML side code now looks as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Benefits of Walking!</title>
</head>
<body>
<p>Physical activity, such as walking,
is important for weight control because it
helps you burn calories. </p><br>
If you add {{time}} minutes of brisk
walking to your daily routine,
you could burn about {{calories}} more calories a day.
</body>
</html>
Explanation: In the code above, we have made use of Expression statements. They should have,
two sets of curly brackets {{}}, and, the key passed by the backend, in between. So it looks like
{{time}} or {{calories}}. The key name should be exactly the same, as present on the backend
side.
Output:
81
Making Decisions, Adding loops Using Expressions and Templates
Apart from sending variable values, we can send a list, add for loops, and,
make decisions as well, using the Expressions statements. To do so, let us
add, code snippets for the same, on Python and HTML side, as shown
below:
# import the Flask library
from flask import Flask, render_template
82
# Route added using a decorator,
# for view function 'joingym'
# Pass the list of todo's and decidegym
# boolean variable, to the HTML file
@[Link]('/gym')
def joingym():
return render_template("[Link]",
todo=joiningGym,
decidegym=True)
</body>
</html>
Let us understand the Python and HTML code files:
• In the Python code, we have added a new view function 'joingym'. The view function
renders, the '[Link]' file, for the route '[Link] invoked
from the browser.
83
• We have prepared a todo list, while joining the gym, in the list variable
'joiningGym'. We are passing the list, to the frontend file, along with the
'decidegym' boolean variable.
• In the HTML file, if the decidegym variable, has the value True, then the todo list
elements, are displayed. It means the if block code executes.
• If it is False, then the Else block is executed, which then displays, the message.
• The for loop and if-else decision logic is written, using Expression statements. They
are written in curly brackets {% %} as shown in the HTML file.
Output: When 'decidegym' variable value is passed as True, while passing values in
render_template() method, of view function joingym().
When 'decidegym' variable value is passed as False, while passing values in render_template()
method, of view function joingym().
84
The Base Layout
Each page in the application will have the same basic layout around a different body. Instead of
writing the entire HTML structure in each template, each template will extend a base template and
override specific sections.
flaskr/templates/[Link]
<!doctype html>
<title>{% block title %}{% endblock %} - Flaskr</title>
<link rel="stylesheet" href="{{ url_for('static',
filename='[Link]') }}">
<nav>
<h1>Flaskr</h1>
<ul>
{% if [Link] %}
<li><span>{{ [Link]['username'] }}</span>
<li><a href="{{ url_for('[Link]') }}">Log Out</a>
{% else %}
<li><a href="{{ url_for('[Link]') }}">Register</a>
<li><a href="{{ url_for('[Link]') }}">Log In</a>
{% endif %}
</ul>
</nav>
<section class="content">
<header>
{% block header %}{% endblock %}
</header>
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
{% block content %}{% endblock %}
</section>
After the page title, and before the content, the template loops over each message returned
by get_flashed_messages(). You used flash() in the views to show error messages, and
this is the code that will display them.
85
There are three blocks defined here that will be overridden in the other templates:
1. {% block title %} will change the title displayed in the browser’s tab and
window title.
2. {% block header %} is similar to title but will change the title displayed on
the page.
3. {% block content %} is where the content of each page goes, such as the login
form or a blog post.
The base template is directly in the templates directory. To keep the others organized, the
templates for a blueprint will be placed in a directory with the same name as the blueprint.
Register
flaskr/templates/auth/[Link]
{% extends '[Link]' %}
{% block header %}
<h1>{% block title %}Register{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post">
<label for="username">Username</label>
<input name="username" id="username" required>
<label for="password">Password</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="Register">
</form>
{% endblock %}
{% extends '[Link]' %} tells Jinja that this template should replace the blocks from the
base template. All the rendered content must appear inside {% block %} tags that override
blocks from the base template.
A useful pattern used here is to place {% block title %} inside {% block header %}. This
will set the title block and then output the value of it into the header block, so that both the window
and page share the same title without writing it twice.
The input tags are using the required attribute here. This tells the browser not to submit the
form until those fields are filled in. If the user is using an older browser that doesn’t support that
86
attribute, or if they are using something besides a browser to make requests, you still want to
validate the data in the Flask view. It’s important to always fully validate the data on the server,
even if the client does some validation as well.
Log In
This is identical to the register template except for the title and submit button.
flaskr/templates/auth/[Link]
{% extends '[Link]' %}
{% block header %}
<h1>{% block title %}Log In{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post">
<label for="username">Username</label>
<input name="username" id="username" required>
<label for="password">Password</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="Log In">
</form>
{% endblock %}
Register A User
Now that the authentication templates are written, you can register a user. Make sure the server is
still running (flask run if it’s not), then go to [Link]
Try clicking the “Register” button without filling out the form and see that the browser shows an
error message. Try removing the required attributes from the [Link] template and
click “Register” again. Instead of the browser showing an error, the page will reload and the error
from flash() in the view will be shown.
87
Fill out a username and password and you’ll be redirected to the login page. Try entering an
incorrect username, or the correct username and incorrect password. If you log in you’ll get an
error because there’s no index view to redirect to yet.
Objective
• Name
• Registration number
• Department
• Level
Project Structure
practical2/
├── venv/
├── [Link]
├── templates/
│ ├── [Link]
88
│ └── [Link]
└── static/
└── [Link]
[Link]
app = Flask(__name__)
students = []
@[Link]("/")
def home():
return render_template("[Link]")
89
@[Link]("/register", methods=["POST"])
def register():
name = [Link]["name"]
reg_no = [Link]["reg_no"]
department = [Link]["department"]
level = [Link]["level"]
student = {
"name": name,
"reg_no": reg_no,
"department": department,
"level": level
[Link](student)
return redirect("/students")
90
@[Link]("/students")
def view_students():
return render_template(
"[Link]",
students=students
if __name__ == "__main__":
[Link](debug=True)
templates/[Link]
<!DOCTYPE html>
<html>
<head>
<title>Student Registration</title>
91
</head>
<body>
<h1>Student Registration</h1>
<label>Name:</label><br>
<br><br>
<label>Registration Number:</label><br>
<br><br>
<label>Department:</label><br>
<br><br>
<label>Level:</label><br>
<br><br>
</form>
<br>
92
<a href="/students">View Students</a>
</body>
</html>
templates/[Link]
<!DOCTYPE html>
<html>
<head>
<title>Registered Students</title>
</head>
<body>
<h1>Registered Students</h1>
{% if students %}
<table border="1">
<tr>
<th>Name</th>
<th>Registration Number</th>
<th>Department</th>
<th>Level</th>
</tr>
{% for student in students %}
<tr>
<td>{{ [Link] }}</td>
<td>{{ student.reg_no }}</td>
<td>{{ [Link] }}</td>
<td>{{ [Link] }}</td>
93
</tr>
{% endfor %}
</table>
{% else %}
<p>No students registered.</p>
{% endif %}
<br>
<a href="/">Register Another Student</a>
</body>
</html>
Concepts Covered
HTML Form
↓
POST Request
↓
Flask Route
↓
[Link]
↓
Python Dictionary
↓
Python List
↓
Jinja for loop
↓
HTML Table
Important: This version stores students only in memory. If you stop Flask, the records
disappear.
94
That limitation leads naturally to Practical 3.
This implementation covers complete CRUD operations (Create, Read, Update, Delete) securely
parameterized to prevent SQL injection vulnerabilities
Project Structure
Create a dedicated project directory with the following structure:
text
student_system/
│
├── [Link] # Initializes the SQLite database & table
├── [Link] # Main Flask application file
└── templates/ # Folder containing HTML front-end templates
├── [Link] # Master template with Bootstrap styling
├── [Link] # Home page displaying student records
├── [Link] # Form to add a new student
└── [Link] # Form to update student details
def init_db():
# Connect to database file (creates it if it doesn't exist)
conn = [Link]('[Link]')
cursor = [Link]()
95
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
roll_no TEXT NOT NULL UNIQUE,
email TEXT NOT NULL,
course TEXT NOT NULL,
grade TEXT NOT NULL
)
''')
[Link]()
[Link]()
print("Database and table initialized successfully.")
if __name__ == '__main__':
init_db()
Use code with caution.
app = Flask(__name__)
app.secret_key = "super_secret_session_key" # Required for flashing user
alerts
def get_db_connection():
"""Establishes a reliable connection to the SQLite database."""
conn = [Link]('[Link]')
conn.row_factory = [Link] # Access columns by name like a
dictionary
return conn
96
roll_no = [Link]['roll_no']
email = [Link]['email']
course = [Link]['course']
grade = [Link]['grade']
return render_template('[Link]')
if [Link] == 'POST':
name = [Link]['name']
roll_no = [Link]['roll_no']
email = [Link]['email']
course = [Link]['course']
grade = [Link]['grade']
97
[Link]()
return render_template('[Link]', student=student)
if __name__ == '__main__':
[Link](debug=True)
Use code with caution.
The core framework utilizing a modern UI wrapper (Bootstrap 5) for alert routing and
responsiveness. [1, 2]
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Student Management System</title>
<link href="[Link] rel="stylesheet">
</head>
<body class="bg-light">
<nav class="navbar navbar-dark bg-dark mb-4">
<div class="container">
<a class="navbar-brand" href="{{ url_for('index') }}">
Student Management System</a>
</div>
</nav>
<div class="container">
<!-- System-wide Alert System -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }} alert-
dismissible fade show" role="alert">
{{ message }}
98
<button type="button" class="btn-close" data-bs-
dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
templates/[Link]
Displays the full dynamic register populated by your SQLite database fetch. [1]
html
{% extends '[Link]' %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-3">
<h2>Student Records</h2>
<a href="{{ url_for('add_student') }}" class="btn btn-primary">+ Add
New Student</a>
</div>
<div class="table-responsive bg-white p-3 rounded shadow-sm">
<table class="table table-striped align-middle">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Name</th>
<th>Roll No</th>
<th>Email</th>
<th>Course</th>
<th>Grade</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for student in students %}
<tr>
<td>{{ student['id'] }}</td>
<td>{{ student['name'] }}</td>
<td>{{ student['roll_no'] }}</td>
<td>{{ student['email'] }}</td>
<td>{{ student['course'] }}</td>
<td><span class="badge bg-secondary">{{ student['grade']
}}</span></td>
<td>
<div class="d-flex gap-2">
<a href="{{ url_for('edit_student',
id=student['id']) }}" class="btn btn-sm btn-warning">Edit</a>
99
<form action="{{ url_for('delete_student',
id=student['id']) }}" method="POST" onsubmit="return confirm('Are you sure
you want to delete this student?');">
<button type="submit" class="btn btn-sm btn-
danger">Delete</button>
</form>
</div>
</td>
</tr>
{% else %}
<tr>
<td colspan="7" class="text-center text-muted">No student
records found.</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
Use code with caution.
templates/[Link]
html
{% extends '[Link]' %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-6 bg-white p-4 rounded shadow-sm">
<h3 class="mb-3">Add Student</h3>
<form method="POST">
<div class="mb-3"><label class="form-label">Full
Name</label><input type="text" name="name" class="form-required form-
control" required></div>
<div class="mb-3"><label class="form-label">Roll
Number</label><input type="text" name="roll_no" class="form-control"
required></div>
<div class="mb-3"><label class="form-
label">Email</label><input type="email" name="email" class="form-control"
required></div>
<div class="mb-3"><label class="form-
label">Course</label><input type="text" name="course" class="form-control"
required></div>
<div class="mb-3"><label class="form-
label">Grade</label><input type="text" name="grade" class="form-control"
required></div>
<button type="submit" class="btn btn-success">Save
Record</button>
<a href="{{ url_for('index') }}" class="btn btn-
secondary">Cancel</a>
</form>
</div>
</div>
{% endblock %}
Use code with caution.
100
templates/[Link]
html
{% extends '[Link]' %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-6 bg-white p-4 rounded shadow-sm">
<h3 class="mb-3">Modify Student Profile</h3>
<form method="POST">
<div class="mb-3"><label class="form-label">Full
Name</label><input type="text" name="name" class="form-control" value="{{
student['name'] }}" required></div>
<div class="mb-3"><label class="form-label">Roll
Number</label><input type="text" name="roll_no" class="form-control"
value="{{ student['roll_no'] }}" required></div>
<div class="mb-3"><label class="form-
label">Email</label><input type="email" name="email" class="form-control"
value="{{ student['email'] }}" required></div>
<div class="mb-3"><label class="form-
label">Course</label><input type="text" name="course" class="form-control"
value="{{ student['course'] }}" required></div>
<div class="mb-3"><label class="form-
label">Grade</label><input type="text" name="grade" class="form-control"
value="{{ student['grade'] }}" required></div>
<button type="submit" class="btn btn-warning">Update
Record</button>
<a href="{{ url_for('index') }}" class="btn btn-
secondary">Cancel</a>
</form>
</div>
</div>
{% endblock %}
101
Student Management System with SQLite
1. Learning Objectives
2. What is SQLite?
Unlike MySQL or PostgreSQL, SQLite does not require a separate database server.
[Link]
This makes SQLite particularly suitable for teaching and small applications.
102
Field Purpose
id Unique identifier
The function:
def get_db_connection():
connection = [Link](DATABASE)
connection.row_factory = [Link]
return connection
[Link]
The statement:
[Link](DATABASE)
This line:
connection.row_factory = [Link]
Instead of:
student[1]
103
we can use:
student["name"]
The function:
def create_table():
executes:
The phrase:
IF NOT EXISTS
means:
This prevents the application from trying to recreate the table every time it starts.
7. Inserting a Student
GET
/add
↓
Add Student Form
104
POST
Form
↓
POST /add
↓
Insert into database
8. SQL INSERT
[Link]("""
INSERT INTO students
(name, reg_no, department, level)
VALUES (?, ?, ?, ?)
""", (name, reg_no, department, level))
This is preferable to constructing SQL statements through string concatenation because it helps
protect against SQL injection.
9. Why commit()?
[Link]()
is called.
105
This permanently saves the transaction to the database.
student_list = [Link](
"SELECT * FROM students"
).fetchall()
means:
Retrieve all columns and all records from the students table.
[Link]
using:
return render_template(
"[Link]",
students=student_list
)
For example:
106
<td>{{ [Link] }}</td>
The database therefore becomes the source of the information displayed on the web page.
@[Link]("/delete/<int:id>")
def delete_student(id):
The:
<int:id>
For example:
/delete/5
means:
id = 5
with:
(id,)
107
CRUD Meaning Application
CREATE ✓
READ ✓
UPDATE ✗
DELETE ✓
Suggested student extension
/edit/<id>
• Name
• Registration number
• Department
• Level
108
109