Fullstack Development - Module 2
Fullstack Development - Module 2
6th SEMESTER – B. E
Academic Year: 2023 – 2024 (Even)
Fullstack Development
Presenter: Mrs. Shilpashree S
Assistant Professor, Dept. of CSE,
SJB Institute of Technology
Module-2: Django Templates and Models
● In all our previous code, the HTML was hard-coded directly in our
Python code which may lead to several problems:
○ Any change to the design of the page requires a change to the Python code. The design of
a site tends to change far more frequently than the underlying Python code, so it would
be convenient if the the design could change without needing to modify the Python code.
○ • Writing Python code and designing HTML are two different disciplines, and most
professional Web development environments split these responsibilities between
separate people (or even separate departments). Designers and HTML/CSS coders
shouldn’t have to edit Python code to get their job done; they should deal with HTML.
○ • Similarly, it’s most efficient if programmers can work on Python code and designers
can work on templates at the same time, rather than one person waiting for the other to
finish editing a single file that contains both Python and HTML.
4.1 Template System Basics
● A template defines placeholders and various bits of basic logic (i.e., template
tags) that regulate how the document should be displayed.
Things to Understand
● The Example contains variables and template tags.
● Any text surrounded by a pair of braces (e.g., {{ person_name }}) is a variable. This
means “insert the value of the variable with the given name.”
● Any text that’s surrounded by curly braces and percent signs (e.g., {% if
ordered_warranty %}) is a template tag.
● This example template contains two tags: the {% for item in item_list %} tag (a for
tag) and the {% if ordered_warranty %} tag (an if tag).
● A for tag acts as a simple loop construct, letting you loop over each item in a
sequence. An if tag, as you may expect, acts as a logical “if” statement
● this template has an example of a filter, with which you can alter the display of a
variable.The date filter formats dates in a given format, as specified by that
argument. Filters are attached using a pipe character (|), as a reference to Unix
pipes.
4.2 Using the Template System
To use the template system in Python code, just follow these two steps:
1. Create a Template object by providing the raw template code as a string. Django
also offers a way to create Template objects by designating the path to a template
file on the filesystem; we’ll examine that in a bit.
2. Call the render() method of the Template object with a given set of variables
(i.e., the context). This returns a fully rendered template as a string, with all of the
variables and block tags evaluated according to the context.
4.2.1 Creating Template Objects
The Template class lives in the django.template module, and the constructor
takes one argument, the raw template code.
If your template code includes any syntax errors, the call to Template() will cause a
TemplateSyntaxError exception
The system raises a TemplateSyntaxError exception for any of the following cases:
● Dictionary Lookup
● Attribute Lookup
● Method Lookup
● List Index Lookup
Dot Lookups can be nested Multiple Levels Deep
4.3 Basic Template Tags and Filters
4.3.1 Tags
4.3.1.1 if/else:
The {% if %} tag evaluates a variable, and if that variable is “true” (i.e., it exists,
is not empty, and is not a false Boolean value), the system will display
everything between {% if %} and {% endif %}.
{% if today_is_weekend %}
<p>Welcome to the weekend!</p>
{% endif %}
An {% else %} tag is optional:
{% if today_is_weekend %}
<p>Welcome to the weekend!</p>
{% else %}
<p>Get back to work.</p>
{% endif %}
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
Python “Truthiness”
In Python
● Empty list ([])
● Tuple (())
● Dictionary ({})
● String ('')
● Zero (0)
● Special object None
{% if not athlete_list %}
There are no athletes.
{% endif %}
{% if athlete_list or coach_list %}
There are some athletes or some coaches.
{% endif %}
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
{% if athlete_list %}
{% if coach_list or cheerleader_list %}
We have athletes, and either coaches or cheerleaders!
{% endif %}
{% endif %}
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
Multiple uses of the same logical operator are fine, but you can’t combine
different operators. For example, this is valid:
Example:
{% if athlete_list or coach_list or parent_list or teacher_list %}
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
There is no {% elif %} tag. Use nested {% if %} tags to accomplish the same
thing:
{% if athlete_list %}
<p>Here are the athletes: {{ athlete_list }}.</p>
{% else %}
<p>No athletes are available.</p>
{% if coach_list %}
<p>Here are the coaches: {{ coach_list }}.</p>
{% endif %}
{% endif %}
Clarification on {% if %} Tags:
● Combining and and or: You can indeed combine and and or clauses within a
single {% if %} tag to create more complex conditional logic. Parentheses are
not required for controlling the order of operations. The Django template language
has its own evaluation rules for these operators
4.3.1.2 for
● The {% for %} tag allows you to loop over each item in a
sequence.
● As in Python’s for statement, the syntax is for X in Y, where Y
is the sequence to loop over and X is the name of the variable
to use for a particular cycle of the loop.
● Each time through the loop, the template system will render
everything between {% for %} and {% endfor %}.
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
4.3.1.2 for
For example, you could use the following to display a list of
athletes given a variable athlete_list:
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
4.3.1.2 for
Add reversed to the tag to loop over the list in reverse:
● There is no support for “breaking out” of a loop before the loop is finished.
{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}
Note:
The magic forloop variable is only available within loops. After the template
parser has reached {% endfor %}, forloop disappears.
Examples
1. Develop a django App to check if a number passed through the URL is a
prime number and return a response.
2. Develop a simple Django App that displays a unordered list of fruits and
ordered list of selected students for an event.
{# This is a comment #}
A comment cannot span multiple lines. This limitation improves template parsing
performance.
4.3.2 Filters
● Template filters are simple ways of altering the value of variables before they’re displayed.
Filters look like this:
{{ name|lower }}
● Filters can be chained—that is, the output of one filter is applied to the next. Here’s a
common idiom for escaping text contents, and then converting line breaks to <p> tags:
{{ my_text|escape|linebreaks }}
● Some filters take arguments. A filter argument looks like this:
{{ bio|truncatewords:"30" }}
● Filter arguments that contain spaces must be quoted; for example, to join a list with
commas and spaces you’d use {{ list|join:", " }}
Because it’s such a common idiom to load a template, fill a Context, and return an
HttpResponse object with the result of the rendered template, Django provides a
shortcut that lets you do those things in one line of code. This shortcut is a
function called render(), which lives in the module django.shortcuts.
4.6 Template Loading - Contd..
4.6.2 The locals() Trick
If you’re one of those lazy programmers and you like keeping code particularly
concise, you can take advantage of a built-in Python function called locals(). It
returns a dictionary mapping all local variable names to their values.
One thing to watch out for when using locals() is that it includes every local
variable, which may comprise more variables than you actually want your
template to have access to.
4.6 Template Loading - Contd..
4.6.3 Subdirectories in get_template()
You might like to store templates in subdirectories of your template directory,
and that’s fine. In fact, we recommend doing so; some more advanced Django
features (such as the generic views system) expect this template layout as a
default convention.
Storing templates in subdirectories of your template directory is easy. In your
calls to get_template(), just include the subdirectory name and a slash before the
template name
4.6 Template Loading - Contd..
4.6.4 The include Template Tag
{% include %}: This tag allows you to include the contents of another template.
The argument to the tag should be the name of the template to include, and the
template name can be either a variable or a hard-coded (quoted) string, in either
single or double quotes.
Anytime you have the same code in multiple templates, consider using an {%
include %} to remove the duplication.
4.7 Template Inheritance
Template inheritance lets you build a base “skeleton” template that contains all the
common parts of your site and defines “blocks” that child templates can override.
The first step is to define a base template—a skeleton of your page that child templates
will later fill in.
It’s the job of child templates to override, or add to, or leave alone the contents of the
blocks.
We’re using a template tag here that you haven’t seen before: the {% block %} tag. All the
{% block %} tags do is tell the template engine that a child template may override those
portions of the template.
4.7 Template Inheritance - Contd..
Here are some tips for working with template inheritance:
● If you use {% extends %} in a template, it must be the first template tag in that template.
Otherwise, template inheritance won’t work.
● Generally, the more {% block %} tags in your base templates, the better. Remember, child
templates don’t have to define all parent blocks, so you can fill in reasonable defaults in a
number of blocks, and then define only the ones you need in the child templates. It’s better
to have more hooks than fewer hooks.
● If you find yourself duplicating code in a number of templates, it probably means you
should move that code to a {% block %} in a parent template.
● If you need to get the content of the block from the parent template, the {{ block.super }}
variable will do the trick. This is useful if you want to add to the contents of a parent block
instead of completely overriding it.
● You may not define multiple{% block %}tags with the same name in the same template.
4.7 Template Inheritance - Contd..
If a visitor is a senior citizen (is_senior is True) and has a valid park pass
(has_park_pass is True), display a welcome message with a discount offer.
Django follows this MVC pattern closely enough that it can be called an MVC
framework. Here’s roughly how the M, V, and C break down in Django:
• V, the portion that selects which data to display and how to display it, is handled
by views and templates.
• M stands for “Model,” the data access layer. This layer contains anything and everything about
the data: how to access it, how to validate it, which behaviors it has, and the relationships
between the data.
• T stands for “Template,” the presentation layer. This layer contains presentation-related
decisions: how something should be displayed on a Web page or other type of document.
• V stands for “View,” the business logic layer. This layer contains the logic that access the model
and defers to the appropriate template(s). You can think of it as the bridge between models and
templates.
A bit about ORM…
In Django, ORM (Object-Relational Mapper) acts as a bridge between your Python objects (models) and the
underlying relational database. It essentially translates your object-oriented code into database queries and
vice versa. Here's a deeper look at how it works:
1. Model Definition: You define your data structures using Django models (typically in models.py). These
models represent your database tables and their corresponding fields.
2. Mapping: The ORM maps each model class to a database table and each model field to a database
column.
3. Object Interactions: When you interact with model objects in your Python code (e.g., creating a new
object, saving changes, or querying for data), the ORM translates those actions into the appropriate SQL
statements.
4. Query Construction: You can construct complex database queries using Django's QuerySet API. This API
provides a way to filter, order, and aggregate data without writing raw SQL.
5. Database Interaction: The ORM executes the generated SQL queries on the underlying database and
retrieves or modifies the data as needed.
6. Object Conversion: The ORM converts the retrieved database results into Python objects that correspond
to your models.
5.3 Configuring the Database
First, we need to take care of some initial configuration: we need to tell Django
which database server to use and how to connect to it.
● PostgreSQL
● MariaDB
● MySQL
● Oracle
● SQLite
5.3 Configuring the Database - Contd..
Using a 3rd-party database backend:
In addition to the officially supported databases, there are backends provided by 3rd parties that allow you
to use other databases with Django:
● CockroachDB
● Firebird
● Google Cloud Spanner
● Microsoft SQL Server
● Snowflake
● TiDB
● YugabyteDB
5.3 Configuring the Database - Contd..
Database configuration lives in the Django settings file, called settings.py by default. Edit
settings.py file and look for the database settings:
DATABASE_ENGINE = ''
DATABASE_NAME = ''
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''
5.3 Configuring the Database - Contd..
Here’s a rundown of each setting:
• DATABASE_ENGINE tells Django which database engine to use. If you’re using
a database with Django, DATABASE_ENGINE must be set to one of the Databases
shown below:
(Django officially supports the following databases:)
❏ PostgreSQL
❏ MariaDB
❏ MySQL
❏ Oracle
❏ SQLite
**Note that for whichever database back-end you use, you’ll need to download
and install the appropriate database adapter.
5.3 Configuring the Database - Contd..
● DATABASE_NAME tells Django the name of your database. If you’re using SQLite, specify the full filesystem
path to the database file on your filesystem (e.g., '/home/django/mydata.db').
● DATABASE_USER tells Django which username to use when connecting to your database. If you’re using
SQLite, leave this blank.
● DATABASE_PASSWORD tells Django which password to use when connecting to your database. If you’re
using SQLite or have an empty password, leave this blank.
● DATABASE_HOST tells Django which host to use when connecting to your database. If your database is on the
same computer as your Django installation (i.e., localhost), leave this blank. If you’re using SQLite, leave this
blank. MySQL is a special case here. If this value starts with a forward slash ('/') and you’re using MySQL,
MySQL will connect via a Unix socket to the specified socket, for example:
DATABASE_HOST = '/var/run/mysql'
If you’re using MySQL and this value doesn’t start with a forward slash, then this value is assumed to be the
host.
● DATABASE_PORT tells Django which port to use when connecting to your database. If you’re using SQLite,
leave this blank. Otherwise, if you leave this blank, the underlying database adapter will use whichever port is
default for your given database server. In most cases, the default port is fine, so you can leave this blank.
5.3 Configuring the Database - Contd..
● First, from within the project directory, run the command
python manage.py shell.
● Once you’ve entered the shell, type these commands to test your database
configuration:
>>> from django.db import connection
>>> cursor = connection.cursor()
If nothing happens, then your database is configured properly. Otherwise,
check the error message for clues about what’s wrong.
Database Configuration Error Messages
5.3 Creating the App
There’s one requirement regarding the app convention:
“If you’re using Django’s database layer (models), you must create a
Django app. Models must live within apps. Thus, in order to start writing
our models, we’ll need to create a new app.”
python manage.py startapp app_name
5.5 Defining Models in Python
A model is the single, definitive source of information about your data. It contains
the essential fields and behaviors of the data you’re storing. Generally, each
model maps to a single database table.
The basics:
Each model is a Python class that subclasses django.db.models.Model.
Each attribute of the model represents a database field.
With all of this, Django gives you an automatically-generated database-access
API;
5.5 Defining Models in Python - Contd..
● A Django model is a description of the data in your database, represented as
Python code.
● It’s your data layout — the equivalent of your SQL CREATE TABLE statements
— except it’s in Python instead of SQL, and it includes more than just
database column definitions.
● Django uses a model to execute SQL code behind the scenes and return
convenient Python data structures representing the rows in your database
tables.
If you know about databases, you might wonder, "Why define data models
in both Python and SQL? Isn't that redundant?" Django uses this approach
for several reasons:
● For Django to provide easy ways to access data, it needs to know the database
layout. There are two ways to do this:
○ Describe the data explicitly in Python.
○ Inspect the database at runtime to figure out the data models.
The second method might seem simpler because all the information
about your tables is in one place. However, it has some problems.
■ First, inspecting the database at runtime takes extra time and resources. Doing this
every time the framework processes a request or when the server starts would be too
slow. Django developers aim to minimize this overhead, which helps keep Django faster
than other similar frameworks.
■ Second, some databases, especially older versions of MySQL, do not store enough
information for accurate inspection.
If you know about databases, you might wonder, "Why define data models
in both Python and SQL? Isn't that redundant?" Django uses this approach
for several reasons: (Contd..)
● Writing Python is fun, and keeping everything in Python limits the number of times your
brain has to do a “context switch.” It helps productivity if you keep yourself in a single
programming environment/mentality for as long as possible. Having to write SQL, then
Python, and then SQL again is disruptive.
● Having data models stored as code rather than in your database makes it easier to keep your
models under version control. This way, you can easily keep track of changes to your data
layouts.
● SQL allows for only a certain level of metadata about a data layout. Most database systems,
for example, do not provide a specialized data type for representing email addresses or
URLs. Django models do. The advantage of higher-level data types is higher productivity and
more reusable code.
● SQL is inconsistent across database platforms. If you’re distributing a Web application, for
example, it’s much more pragmatic to distribute a Python module that describes your data
layout than separate sets of CREATE TABLE statements for MySQL, PostgreSQL, and SQLite.
5.6 Your First Model - Quick Example
The first step in using this database layout with Django is to express it as Python code.
This example model defines a Person, which has a first_name and last_name:
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
first_name and last_name are fields of the model. Each field is specified as a class attribute, and
each attribute maps to a database column.
5.6 Your First Model - Quick Example
The first thing to notice is that each model is represented by a Python class that
is a subclass of django.db.models.Model.
The parent class, Model, contains all the machinery necessary to make these
objects capable of interacting with a database — and that leaves our models
responsible solely for defining their fields, in a nice and compact syntax.
Person model would create a database table like this:
);
● Each model generally corresponds to a single database table, and each
attribute on a model generally corresponds to a column in that database
table.
● The attribute name corresponds to the column’s name, and the type of field
(e.g., CharField) corresponds to the database column type (e.g., varchar).
Some technical notes:
• Table names are automatically generated by combining the name of the app and the lowercase name of
the model. You can override this behavior.
• As we mentioned earlier, Django adds a primary key for each table automatically — the id fields. You can
override this, too.
• By convention, Django appends "_id" to the foreign key field name. As you might have guessed, you can
override this behavior, too.
• These CREATE TABLE statements are tailored to the database you’re using, so database-specific field
types such as auto_increment (MySQL), serial (PostgreSQL), or integer primary key (SQLite) are handled
for you automatically. The same goes for quoting of column names (e.g., using double quotes or single
quotes). This example output is in PostgreSQL syntax.
Note:The sqlall command doesn’t actually create the tables or otherwise touch your database — it just
prints output to the screen so you can see what SQL Django would execute if you asked it.
Django provides an easier way of committing the SQL to the database. Run the
syncdb command, like so:
Migration workflow:
);
def __str__(self):
return self.title
CREATE
SQL: Django:
INSERT INTO books (title, author, isbn) book = Book(title="The Hitchhiker's Guide to
VALUES ('The Hitchhiker\'s Guide to the the Galaxy", author="Douglas Adams",
Galaxy', 'Douglas Adams', '978-0345391803'); isbn="978-0345391803")
book.save()
Read
SQL: Django:
WHERE id = 1; book.save()
DELETE
SQL: Django:
book.delete()