Tutorial 4: Web Design using HTML and CSS3 & Data Update and Delete Methods
Platform-Based Programming (CSGE602022) — Organized by the Faculty of Computer Science Universitas Indonesia, Odd Semester 2023/2024
Learning Objectives
After completing this tutorial, students are expected to be able to:
- Understand the concept of data update and delete.
- Understand how to update and delete data in Django.
- Understand the tag arrangement in HTML5.
- Know the variety of HTML5 tags.
- Understand CSS syntax.
- Understand the static files concept in Django.
- Understand the usage of selector in CSS.
Introduction to HTML
HyperText Markup Language (HTML) is a standard markup language for a document shown on a web browser. HTML defines the structure of the content of a website.
You can learn and try HTML for yourself here.
You can read the differences between HTML and HTML5 here.
Introduction to CSS
What is CSS?
Cascading Style Sheets (CSS) is a language used to describe the appearance and format of a website written in a markup language (such as HTML). CSS is useful to enhance the appearance of a website, making it more attractive.
You can learn the differences between CSS and CSS3 here.
CSS Syntax
In general, CSS is written as follows:
selector {
properties: value;
}
You can learn and try CSS for yourself here.
There are 3 types of CSS:
- Inline Styles
- Internal Style Sheet
- External Style Sheet
You can learn more about those 3 types here ini.
Note that if you are creating an External Style Sheet, you have to to add the tag {% load staticfiles %}
in your Django HTML file. The example is as follows:
{% load staticfiles %}
<html>
<head>
<title>CSS Tutorial Yay</title>
<link rel="stylesheet" href="{% static 'css/tutorial.css' %}" />
</head>
<body>
<div>
<h1>CSS Tutorial Yay</h1>
</div>
<div id="main">
<div>
<p>published: 27 September 2023</p>
<h1><a href="">My CSS Tutorial</a></h1>
<p>T!</p>
</div>
</div>
</body>
</html>
This needs to be done because CSS is a static file in Django. Static files will be explained in the next section.
Additional Note
If there is more than one style defined for an element/tag, then the applied style for that element/tag is the one that has the higher priority. The priority order is as follows (number 1 has the highest priority):
- Inline style
- Internal style
- External style
- Browser default
Static files in Django
In Django, there are some files called static files. Static files are supporting files used in an HTML file of a website. Examples of static files are CSS, JavaScript, and images.
The setting for static files is located in settings.py
:
...
# Static files (CSS, JavaScript, Images)
# httpsdocs.djangoproject.comen1.9howtostatic-files
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
STATIC_URL = 'static'
...
The settings.py
contains:
STATIC_ROOT
, which is used to tell Django the absolute path of the directory location where the commandcollectstatic
will collect static files.STATIC_URL
, which is a URL that can be publicly accessed to obtain the static files.
The collectstatic
command is used to collect static files from all app so that the files can be easily accessed.
You can read more about static files here.
CSS Selectors
In this tutorial, we will explore three types of CSS selectors: Element Selector, ID Selector, and Class Selector.
Element Selector
The Element Selector allows us to apply styles to all elements with the same HTML tag.
Example of using the Element Selector:
<body>
<div>
<h1>Tutorial CSS Yay :D</h1>
<h2>Tutorial CSS Yay Yay :D</h2>
</div>
...
</body>We can use the element itself as a selector in a CSS file. The Element Selector uses the format [tag_name] (without any preceding symbol).
h1 {
color: #fca205;
font-family: "Monospace";
font-style: italic;
}ID Selector
The ID Selector uses the ID of an HTML tag as its selector. IDs are unique within a single web page and can be added to HTML template pages.
Example of using the ID Selector in an HTML template:
<body>
<div id="header">
<h1>Tutorial CSS Yay :D</h1>
</div>
...
</body>Then, we can use the ID as a selector in a CSS file. ID selectors use the format #[id_name] (always preceded by #).
#header {
background-color: #f0f0f0;
margin-top: 0;
padding: 20px 20px 20px 40px;
}Class Selector
The Class Selector allows us to group elements with similar characteristics.
Example of using Class Selector in an HTML template:
...
<div id="main">
<div class="content_section">
<p class="date">published: 28 September 2022</p>
<h2><a href="">My CSS tutorial</a></h2>
<p id="content_1">So ez!</p>
</div>
<div class="content_section">
<p class="date ">published: 29 September 2022</p>
<h2><a href="">Your CSS tutorial</a></h2>
<p id="content_2">So ez ez!</p>
</div>
<div class="content_section">
<p class="date">published: 30 September 2022</p>
<h2><a href="">Our CSS tutorial</a></h2>
<p id="content_3">So ez ez ez!</p>
</div>
</div>
...Then, we can use the Class as a selector in a CSS file. Class selectors use the format .[class_name] (preceded by . ).
.content_section {
background-color: #3696e1;
margin-bottom: 30px;
color: #000000;
font-family: cursive;
padding: 20px 20px 20px 40px;
}For a deeper understanding of CSS Selector Reference, you can read the reference here.
CSS Tips & Tricks
Understanding CSS Combinators
Combinators in CSS connect two or more selectors to further refine the selected elements.
There are four types of combiners in CSS. Here's a summary of their usage:
Combinator | Example | Explanation |
---|---|---|
Descendant selector (space) | div p | Selects all p elements that are descendants of div elements. |
Child selector (>) | div > p | Selects all p elements that are children of div elements. |
Adjacent sibling selector (+) | div + p | Selects the first p element that directly follows a div element (must share the same parent). |
General sibling selector (~) | div ~ p | Selects all p elements that are siblings and come after a div element. |
You can learn more about combinators here.
Understanding CSS Pseudo-classes
Pseudo-classes are used to define a special state of an element. The syntax for using pseudo-classes is as follows:
selector:pseudo-class {
property: value;
}
Here are some examples of pseudo-classes:
| Pseudo-class | Applies Styles to ... |
| -------- | -------- |
| :link
| Links that have not been visited yet. |
| :visited
| Links that have been visited. |
| :hover
| Elements when a user hovers their cursor over them. |
| :active
| Elements when a user hovers their cursor over them. |
| :focus
| Elements when they are in focus, like an input field when clicked. |
| :checked
| Elements like checkboxes or radio buttons that are checked. |
| :disabled
| Elements that are unresponsive, like disabled buttons. |
You can learn more about pseudo-classes here.
Understanding the CSS Box Model
The CSS box model essentially wraps each HTML element and consists of:
- Content: The content inside the box (where text and images appear).
- Padding: The transparent space around the content.
- Border: The border around the content and padding.
- Margin: The transparent space around the border.
You can learn more about margin, border, and padding here.
Introduction to Bootstrap & Tailwind
In the field of web development, there are many CSS frameworks that developers commonly use. The primary purpose of a CSS framework is to streamline the work of programmers. Two popular CSS frameworks today are Bootstrap and Tailwind. Both of these frameworks offer various advantages compared to using plain CSS. Here are the benefits of using a framework compared to regular CSS:
- Faster Development: Frameworks like Bootstrap provide pre-built components, eliminating the need to write CSS from scratch.
- Built-in Responsiveness: Frameworks like Bootstrap and Tailwind are designed with responsiveness in mind.
- Scalability: CSS frameworks provide a well-organized structure for growing projects over time.
Bootstrap and Tailwind, as frameworks, have significant differences:
Tailwind | Bootstrap |
---|---|
Tailwind CSS builds layouts by combining pre-defined utility classes. | Bootstrap uses predefined styles and components with ready-made designs that can be used directly. |
Tailwind CSS has a smaller CSS file compared to Bootstrap and only loads the utility classes used. | Bootstrap has a larger CSS file due to the inclusion of many predefined components. |
Tailwind CSS offers high flexibility and adaptability to projects. | Bootstrap often produces more consistent designs throughout a project as it uses predefined components. |
Learning Tailwind CSS can have a steeper learning curve because it requires understanding and combining available utility classes. | Bootstrap offers a quicker learning curve for beginners as they can start with predefined components. |
Responsive Web Design
Responsive web design is a web design approach that aims to create websites that look good on all devices, including desktops, tablets, mobile phones, and more. Responsive web design does not change the content of the website but adapts its appearance and layout based on the device's screen width and capabilities. In responsive web design, specific views may require CSS assistance, such as resizing or enlarging elements.
One way to test if a website uses responsive web design is to access the website and enable the Toggle Device Mode
feature in your web browser. This feature allows you to see how the website appears on various devices, such as desktops, tablets, or smartphones, without changing the browser window's size.
Here's how to access this feature in Google Chrome:
- Windows/Linux :
CTRL + SHIFT + M
- Mac :
Command + Shift + M
Another practical way is to right-click in the browser and select "Inspect Element/Inspect" to open the Dev Tools, which can be very helpful.
To learn more about Responsive Web Design, you can refer to this guide.
Tutorial: Adding Bootstrap
During this PBP course, we will focus on learning CSS using the Bootstrap framework. Here are the steps you need to take to complete this tutorial.
Open your Django project shopping_list and then open the
base.html
file that was previously created in the templates folder located in your project's root directory.Inside the
templates/base.html
file, add the<meta name="viewport">
tag. With this tag, your web page will adapt to the size and behavior of mobile devices.<head>
{% block meta %}
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
{% endblock meta %}
</head>Add Bootstrap and JavaScript
CSS:
<head>
{% block meta %}
...
{% endblock meta %}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>JS:
<head>
...
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha384-KyZXEAg3QhqLMpG8r+J4jsl5c9zdLKaUk5Ae5f5b1bw6AUn5f5v8FZJoMxm6f5cH1" crossorigin="anonymous"></script>
</head>Optional If you want to use the dropdowns, popovers, and tooltips provided by the Bootstrap framework, you need to add these two lines of JavaScript below the JavaScript code you've previously created.
<head>
...
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous"></script>
</head>
Reference: Get Started with Bootstrap 5.3
Tutorial: Adding Navbar
Add a navigation bar (you can use Bootstrap) to your main.html
page. Display your name and a logout button on the navigation bar. You can refer to how to create a navigation bar in Bootstrap with the following documentation and customize the navigation bar as you like.
Tutorial: Adding Edit Function to the Application
Open
views.py
in themain
subdirectory, and create a new function callededit_product
that acceptsrequest
andid
parameters.Add the following code to the
edit_product
functiondef edit_product(request, id):
# Get product by ID
product = Product.objects.get(pk = id)
# Set product as instance of form
form = ProductForm(request.POST or None, instance=product)
if form.is_valid() and request.method == "POST":
# Save the form and return to home page
form.save()
return HttpResponseRedirect(reverse('main:show_main'))
context = {'form': form}
return render(request, "edit_product.html", context)Create a new HTML file called
edit_product.html
in themain/templates
subdirectory. Add the following code.{% extends 'base.html' %}
{% load static %}
{% block content %}
<h1>Edit Product</h1>
<form method="POST">
{% csrf_token %}
<table>
{{ form.as_table }}
<tr>
<td></td>
<td>
<input type="submit" value="Edit Product"/>
</td>
</tr>
</table>
</form>
{% endblock %}Open
urls.py
in themain
directory and import theedit_product
function that has been created.from main.views import edit_product
Add the path url to
urlpatterns
to access the function that was imported earlier....
path('edit-product/<int:id>', edit_product, name='edit_product'),
...Open
main.html
in themain/templates
subdirectory. Add the following code to the last<td>
element to make the edit button visible on each row of the table....
<tr>
...
<td>
<a href="{% url 'main:edit_product' product.pk %}">
<button>
Edit
</button>
</a>
</td>
</tr>
...Run your Django project with the command
python manage.py runserver
and open http://localhost:8000 in your favorite browser. After logging in, try to edit the data for a product. If no errors occur, then congratulations, you have successfully added the edit feature!
Tutorial: Adding Delete Function to the Application
Here are the steps to create a delete function:
Create a new function called
delete_product
in theviews.py
file within the main folder. This function should take parametersrequest
andid
. You can use the following code below to create such function:Try to understand the code first! 😉
def delete_product(request, id):
# Get data by ID
product = Product.objects.get(pk=id)
# Delete data
product.delete()
# Return to the main page
return HttpResponseRedirect(reverse('main:show_main'))Open the
urls.py
file in the main folder and import the function you created earlier:from main.views import delete_product
Add a path URL to the
urlpatterns
to access the imported function:...
path('delete/<int:id>', delete_product, name='delete_product'), # adjust the function name
...Open the
main.html
file in themain/templates
folder and modify the existing code to include a delete button for each product:...
<tr>
...
<td>
<a href="{% url 'main:edit_product' product.pk %}">
<button>
Edit
</button>
</a>
<a href="{% url 'main:delete_product' product.pk %}">
<button>
Delete
</button>
</a>
</td>
</tr>
...
Run your Django project and try deleting a product from your favorite browser.
Further Reading
You can open the links below to see some code options that you can use to add a navigation bar:
Contributors
- Alanna
- Alvaro Austin
- Naila Shafirni Hidayat
- Shayna Putri Fitria
- Aidah Novallia Putri (EN Translator)
- Bonaventura Galang (EN Translator)
- Ferry (EN Translator)
Credits
This tutorial was developed based on PBP Odd 2023 and PBP Even 2023 written by the 2023 Platform-Based Programming Teaching Team. All tutorials and instructions included in this repository are designed so that students who are taking Platform-Based Programming courses can complete the tutorials during lab sessions.