0% found this document useful (0 votes)
85 views

Fullstack Development - Module 2

Uploaded by

swarajbharathp
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
85 views

Fullstack Development - Module 2

Uploaded by

swarajbharathp
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 94

||Jai Sri Gurudev ||

Sri AdichunchanagiriShikshana Trust®

SJB INSTITUTE OF TECHNOLOGY


Accredited by NBA & NAAC with ‘A+’ Grade
No. 67, BGS Health & Education City, Dr. Vishnuvardhan Road Kengeri,
Bangalore – 560 060

Department of Computer Science & Engineering


FullStack Development [21CS62]
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 Django template is a string of text that is intended to separate the


presentation of a document from its data.

● 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.

Introduction to Python Interactive Interpreter:

From within the project directory created by django-admin.py startproject, type


python manage.py shell to start the interactive interpreter.
4.2.1 Creating Template Objects(Contd..)
When you create a Template object, the template system compiles the raw template
code into an internal, optimized form, ready for rendering.

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:

● Invalid block tags


● Invalid arguments to valid block tags
● Invalid filters
● Invalid arguments to valid filters
● Invalid template syntax
● Unclosed block tags (for block tags that require closing tags)
4.2.2 Rendering a Template
● Once you have a Template object, you can pass it data by giving it a context.
● A context is simply a set of variables and their associated values. A template
uses this to populate its variable tags and evaluate its block tags.
● A context is represented in Django by the Context class, which lives in the
django.template module.
● Its constructor takes one optional argument: a dictionary mapping variable
names to variable values.
4.2.2 Rendering a Template(Contd...)
Dictionaries and Contexts:
● A Python dictionary is a mapping between known keys and variable values. A
Context is similar to a dictionary, but a Context provides additional
functionality.
● Variable names must begin with a letter (A-Z or a-z) and may contain digits,
underscores, and dots. Variable names are case sensitive.

4.2.2 Rendering a Template(Contd…)
Let’s step through this code one statement at a time:
● First, we import the classes Template and Context, which both live in the module
django.template.
● We save the raw text of our template into the variable raw_template. Note that we use
triple quote marks to designate the string, because it wraps over multiple lines; in Python
code, strings designated with single quote marks cannot be wrapped over multiple lines.
● Next, we create a template object, t, by passing raw_template to the Template class
constructor.
● We import the datetime module from Python’s standard library, because we’ll need it in
the following statement.
● Then, we create a Context object, c. The Context constructor takes a Python dictionary,
which maps variable names to values. Here, for example, we specify that the
person_name is 'John Smith', product is 'Super Lawn Mower', and so forth.
● Finally, we call the render() method on our template object, passing it the context. This
returns the rendered template—that is, it replaces template variables with the actual
values of the variables, and it executes any block tags.
4.2.2 Rendering a Template(Contd…)
Few things worth understanding about the raw string output:

● Django Template Rendering: t.render(c) in Django returns a string containing the


rendered template content. This string itself is not a raw string.
● Interactive Interpreter Behavior: The interactive interpreter, by default, displays
the "raw representation" of the string. This includes escape sequences like \n for
newlines. This is not specific to Django templates, but a general behavior for
strings in the interpreter.
● print Statement: When you use the print statement (print(t.render(c))), Python
interprets the string and displays it with the intended formatting, including line
breaks according to the \n characters.
● Raw Strings (Not Directly Relevant Here): Raw strings (prefixed with r) are not
typically used for defining Django templates. They are helpful in other contexts
where you want backslashes to be interpreted literally within a string.
4.2.3 Multiple Contexts, Same Template
Once you have a Template object, you can render multiple contexts through it, for
example:
4.2.3 Multiple Contexts, Same Template(Contd..)
Whenever you’re using the same template source to render multiple contexts like this,
it’s more efficient to create the Template object once, and then call render() on it
multiple times:
4.2.3 Multiple Contexts, Same Template(Contd..)
Please avoid doing this:
4.2.4 Context Variable Lookup
● The template system elegantly can handle more complex data structures, such as
lists, dictionaries, and custom objects.
● The key to traversing complex data structures in Django templates is the dot
character (.). Use a dot to access dictionary keys, attributes, indices, or methods of
an object.
Python Dictionary to a Template
Dots allow access of object attributes
Example of Custom class object access:
Dots can be used to call methods on objects
Dots are used to access list indices:
Dot Lookup Summary
When the template system encounters a dot in a variable name, it tries the
following lookups, in this order:

● 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

are False in a Boolean context. Everything else is True.


4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
The {% if %} tag accepts and, or, or not for testing multiple variables, or to negate a
given variable. For example:
{% if athlete_list and coach_list %}
Both athletes and coaches are available.
{% endif %}

{% 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 not athlete_list or coach_list %}


There are no athletes or there are some coaches. (OK, so
writing English translations of Boolean logic sounds
stupid; it's not our fault.)
{% endif %}

{% if athlete_list and not coach_list %}


There are some athletes and absolutely no coaches.
{% endif %}
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
● {% if %} tags don’t allow and and or clauses within the same tag, because
the order of logic would be ambiguous. For example, this is invalid:

● The use of parentheses for controlling order of operations is not


supported. If you find yourself needing parentheses, consider
performing logic in the view code in order to simplify the templates. Even
so, if you need to combine and and or to do advanced logic, just use
nested {% if %} tags, for example:
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
Example:

{% 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

“with and having higher precedence than or “


● Use of actual parentheses in the if tag is invalid syntax. If you need them to indicate precedence, you
should use nested if tags. if tags may also use the operators ==, !=, <, >, <=, >=, in, not in, is, and is not
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..

● Make sure to close each {% if %} with an {% endif %}. Otherwise, Django


will throw a
“TemplateSyntaxError.”
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..

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:

{% for athlete in athlete_list reversed %}


...
{% endfor %}
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
4.3.1.2 for

It’s possible to nest{% for %}tags:

{% for country in countries %}


<h1>{{ country.name }}</h1>
<ul>
{% for city in country.city_list %}
<li>{{ city }}</li>
{% endfor %}
</ul>
{% endfor %}
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
4.3.1.2 for

● There is no support for “breaking out” of a loop before the loop is finished.

● Similarly, there is no support for a “continue” statement that would


instruct the loop processor to return immediately to the front of the loop.
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
4.3.1.2 for
The {% for %} tag sets a magic forloop template variable within the loop. This
variable has a few attributes that give you information about the progress of
the loop:
● forloop.counter is always set to an integer representing the number of
times the loop has been entered. This is one-indexed, so the first time
through the loop, forloop.counter will be set to 1. Here’s an example:
{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
● forloop.counter0 is like forloop.counter, except it’s zero-indexed. Its value
will be set to Zero(0) the first time through the loop.
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
● 4.3.1.2 for
● forloop.revcounter is always set to an integer representing the number of
remaining items in the loop.
○ The first time through the loop, forloop.revcounter will be set to the
total number of items in the sequence you’re traversing.
○ The last time through the loop, forloop.revcounter will be set to 1.
● forloop.revcounter0 is like forloop.revcounter, except it’s zero-indexed.
The first time through the loop, forloop.revcounter0 will be set to the
number of elements in the sequence minus 1. The last time through the
loop, it will be set to 0.
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
● 4.3.1.2 for
● forloop.first is a Boolean value set to True if this is the first time through
the loop. This is convenient for special casing:

{% for object in objects %}


{% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
{{ object }}
</li>
{% endfor %}
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
● 4.3.1.2 for
forloop.last is a Boolean value set to True if this is the last time through the
loop. A common use for this is to put pipe characters between a list of links:

{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}

The above template code might output something like this::

Link1 | Link2 | Link3 | Link4


4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
● 4.3.1.2 for
forloop.parentloop is a reference to the forloop object for the parent loop, in
case of nested loops. Here’s an example:
{% for country in countries %}
<table>
{% for city in country.city_list %}
<tr>
<td>Country #{{ forloop.parentloop.counter }}</td>
<td>City #{{ forloop.counter }}</td>
<td>{{ city }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
4.3 Basic Template Tags and Filters
4.3.1 Tags - Contd..
● 4.3.1.2 for

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.

3. Develop a Django App that demonstrates the usage of various forloop


variables within templates.
4.3.1.3 ifequal/ifnotequal
● The Django template system deliberately is not a full-fledged programming
language and thus does not allow you to execute arbitrary Python
statements.
● However, it’s quite a common template requirement to compare two values
and display something if they’re equal—and Django provides an {% ifequal %}
tag for that purpose.
● The {% ifequal %} tag compares two values and displays everything between
{% ifequal %} and {% endifequal %} if the values are equal.
● Just like {% if %}, the {% ifequal %} tag supports an optional {% else %}.
● Only template variables, strings, integers, and decimal numbers are allowed
as arguments to {% ifequal%}.
● Any other types of variables, such as Python dictionaries, lists, or Booleans,
can’t be hard-coded in {% ifequal %}.
4.3.1.4 Comments
Just as in HTML or in a programming language such as Python, the Django
template language allows for comments. To designate a comment, use {# #}:

{# This is a comment #}

The comment will not be output when the template is rendered.

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:", " }}

● Django provides about sixty built-in template filters.


4.3.2 Filters - Contd..
The following are a few of the most important filters
● addslashes: Adds a backslash before any backslash, single quote, or double quote.
This is useful if the produced text is included in a JavaScript string.
● date: Formats a date or datetime object according to a format string given in the
parameter
● escape: Escapes ampersands, quotes, and angle brackets in the given string. This is
useful for sanitizing user-submitted data and for ensuring data is valid XML or
XHTML.
● escape makes these conversions:
○ Converts & to &amp;
○ Converts < to &lt;
○ Converts > to &gt;
○ Converts " (double quote) to &quot;
○ Converts ' (single quote) to &#39;
● length: Returns the length of the value. You can use this on a list or a string, or any
Python object that knows how to determine its length
4.6 Template Loading
4.6.1 render()

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..

Develop a layout.html with a suitable header (containing navigation menu) and


footer with copyright and developer information. Inherit this layout.html and
create 3 additional pages: contact us, About Us and Home page of any website.
Put Your Skills to the Test:
1. Create a template to display a message depending on a user's age:

If the user is under 18, display "Welcome young adventurer!"

If the user is 18 or older, display "Welcome to our website!"

2. Create a template to display information about products on sale:

If a product is on sale (is_on_sale is True), display the discounted price.

Otherwise, display the regular price.


Put Your Skills to the Test:
3. Create a template to display information about visitors to a national park:

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.

If a visitor is either a student (is_student is True) or a military member


(is_military is True), display a welcome message with a special entrance fee.

Otherwise, display a general welcome message.


Put Your Skills to the Test:
4. Create a template to display a list of user reviews for a product:
Loop through a list of reviews in the context and display the reviewer's name, rating,
and review text for each review.
5. Create a template to display a restaurant menu:
Loop through a list of categories in the context.
For each category, display its name.
Then, loop through a list of dishes within that category and display their names and
prices.
Optionally, include an "if" statement to only display dishes that are currently available.
Interacting with a Database: Models
5.2 The MTV Development Pattern

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:

• M, the data-access portion, is handled by Django’s database layer.

• V, the portion that selects which data to display and how to display it, is handled
by views and templates.

• C, the portion that delegates to a view depending on user input, is handled by


the framework itself by following your URLconf and calling the appropriate
Python function for the given URL.
5.2 The MTV Development Pattern - Contd..
Because the “C” is handled by the framework itself and most of the excitement in Django
happens in models, templates, and views, Django has been referred to as an MTV framework. In
the MTV development pattern,

• 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.

Django officially supports the following databases:

● 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:

CREATE TABLE myapp_person (

"id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,

"first_name" varchar(30) NOT NULL,

"last_name" varchar(30) NOT NULL

);
● 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:

● The name of the table, myapp_person, is automatically derived from some


model metadata but can be overridden.
● An id field is added automatically, but this behavior can be overridden.
● The CREATE TABLE SQL in this example is formatted using PostgreSQL
syntax, but it’s worth noting Django uses SQL tailored to the database
backend specified in your settings file.
5.7 Installing the Model
Edit the settings.py file again, and look for the INSTALLED_APPS setting.
INSTALLED_APPS tells Django which apps are activated for a given project.
Add 'app_name' to the INSTALLED_APPS list.
Now that the Django app has been activated in the settings file, we can create the
database tables in our database.
python manage.py validate (Deprecated !!!)
Instead use “python manage.py check”
This command performs various checks on your Django project, including
identifying potential errors and highlighting best practices.
If your models are valid, run the following command for Django to generate
CREATE TABLE statements for your models in the books app:
python manage.py sqlall books (Deprecated since Django 1.9)
Sqlall was designed to print the SQL statements needed to create all tables for a
specific app.
Django recommends using migrations for managing database schema changes.
However, there is a similar command but uses migrations, to print migration SQL
for a specific app:
“python manage.py sqlmigrate app_name 0001_initial”
● App_name is the name of the Django app that contains the migration you
want to inspect.
● Migration_name is the filename of the specific migration you are interested
in.
● Django uses a naming convention with numbers to order migrations.
● Sqlmigrate is the command that displays the SQL statements that Django
would execute to apply the specified migration to your database.
Few things worth noting:

• 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.

• The foreign key relationship is made explicit by a REFERENCES statement.

• 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:

python manage.py syncdb (Deprecated Since Django 1.7)

Reasons for Deprecation:

1. Syncdb was used to create tables, it didn’t handled data migrations or


schema changes
2. It was inconsistent among various databases
3. It lacked version control
Django now uses migrations as the preferred method for managing database
schema changes:

Migration workflow:

1. Create your models in models.py within your app


2. Run “python manage.py makemigrations app_name” to create migration
files for your app. These files track changes to your models.
3. Apply migrations by executing “python manage.py migrate”. This ensures
database schema reflects your model definitions.
Create - Read - Update - Delete
SQL: Django:

CREATE TABLE Book ( from django.db import models

id INT PRIMARY KEY AUTO_INCREMENT, --


Auto-incrementing integer for primary key
class Book(models.Model):
title VARCHAR(255) NOT NULL,
title = models.CharField(max_length=255)
author VARCHAR(100) NOT NULL,
author = models.CharField(max_length=100)
isbn VARCHAR(13) UNIQUE NOT NULL -- Unique
constraint on ISBN to ensure no duplicates isbn = models.CharField(max_length=13)

);

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:

# Get a book by ID # Get a book by its ID

SELECT * FROM books WHERE id = 1; book = Book.objects.get(id=1)

# Get all books # Get all books

SELECT * FROM books; books = Book.objects.all()


UPDATE
SQL: Django:

UPDATE books book = Book.objects.get(pk=1)

SET title = 'The Martian' book.title = "The Martian"

WHERE id = 1; book.save()
DELETE
SQL: Django:

DELETE FROM books WHERE id = 1; book = Book.objects.get(pk=1)

book.delete()

You might also like