Python For Django Framework
Python For Django Framework
Introduction:
Prerequisites
Machine learning
E-commerce platforms
Data analysis
Content management
While both of these frameworks could suit the needs of your next
Python application, there are specific functionalities and levels of
support that each provides. Let's quickly go through the differences.
Expand table
Django Flask
Ideal for data-driven applications Ideal for existing APIs and services
Django and Flask both offer great benefits for your projects. Depending
on the time requirements for app development, one might be better
suited than the other. When you choose a framework, consider the
type and complexity of the application and also the end product.
Before you install Django, first make sure the correct Python version is
installed for the framework. To check your installed version, go to your
command prompt and enter the following command:
# Windows
python --version
# macOS or Linux
python3 --version
After the command runs, the Python version that's installed on your
computer appears. For this module, we're using the latest official
version of Django. Use Python 3 for access to the latest Python
features. If you don't have Python installed, go to the Python website to
download the correct version.
Start by creating a folder to contain the new project. It will also hold
the folder for the virtual environment.
# Windows
md hello_django
cd hello_django
#macOS or Linux
mkdir hello_django
cd hello_django
code .
Create and activate the virtual environment
# Windows
python -m venv venv
.\\venv\\Scripts\\Activate
# macOS or Linux
python3 -m venv venv
source ./venv/bin/activate
Django installation
Django
Project App
There's only one project. There can be many apps within the single projec
Contains the necessary settings or apps for a specific website. Is a component of the larger we
Projects aren't used in other projects. Apps can be used across multipl
Views
URL mapping
As you continue to learn and have more complex file structures, you'll
add more views and URLs for your app. The URLconf function plays a
key role because it allows for a simple way to manage and organize
URLs within the application. It also provides greater freedom to change
path roots without breaking the app.
Inside the terminal window in Visual Studio Code, run the following
command:
BashCopy
django-admin startproject helloproject .
Important
After you run the preceding command, the new project should now be
in your chosen directory. In this instance, you would see a new folder
called helloproject.
Now that the Django project has been created, let's look at the
structure to see what was included.
textCopy
manage.py
helloproject/
__init__.py
asgi.py
settings.py
urls.py
wsgi.py
BashCopy
python manage.py help
asgi.py and wsgi.py serve as the entry point for your web
servers depending on what type of server is deployed.
Now that Django is installed, a project has been created, and we've
examined the project structure, it's time to make sure our project is
working correctly.
BashCopy
python manage.py runserver
We've learned the basics about the Django framework and examined
the folder structure of our project. Now it's time to create our first app!
The Hello, world! app will help you understand how apps are created
and how they work in unison with the Django project.
Inside the terminal window, run the following command to create the
app.
BashCopy
python manage.py startapp hello_world
With this command, Django creates the required folders and files, and
the following structure should now be visible.
textCopy
hello_world/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
Because apps and projects are separate in Django, you must register
your app with the project. This is done by updating
the INSTALLED_APPS variable inside settings.py for the project, adding a
reference to the config class for the app. The config class is found
in apps.py, and is the same name as the project. In our example, the
class will be named HelloWorldConfig.
3. Add the following to the end of the list, inside the square brackets
([ ]):
PythonCopy
'hello_world.apps.HelloWorldConfig',
PythonCopy
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'hello_world.apps.HelloWorldConfig',
]
Congratulations! You've now created your first Django project and app.
Next is to create a path and view to add some functionality.
Paths
Views
PythonCopy
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world!")
Note
With the view created, the next step is to map it to the appropriate
URL, or path.
PythonCopy
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
The most important part of this code is the urlpatterns tuple. This tuple
is where the views and URLs are connected or mapped. As you can
see, we've imported our views.py file so we can use it within
the urlpatterns line.
Register our URLconf with the project
Our newly created URLconf is inside our hello_world application.
Because the project controls all user requests, we need to register
our URLconf in the core urls.py file, which is inside helloproject.
3. Replace the line that reads from django.urls import path with the
following import statement to add include and path.
PythonCopy
from django.urls import include, path
4. Inside the list, underneath the line that reads urlpatterns = [, add
the following code:
PythonCopy
path('', include('hello_world.urls')),
The code underneath the doc comment should now look like the
following sample:
PythonCopy
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('', include('hello_world.urls')),
path('admin/', admin.site.urls),
]
The structure is complete, views were added, and the URLs were
mapped. Now it's time to run your app!
1. Inside the terminal window in Visual Studio Code, run the
following command to start the server again.
BashCopy
python manage.py runserver
http://localhost:8000/
In this module, we'll work on a website for dog shelters. This project
focuses on collecting information for all existing dog shelters and the
dogs they're hoping to place across the United States. The fictional
hope for this app is that dogs will be able to find suitable homes faster
because they'll have individuals looking to adopt them from around the
United States and not just their local area.
Requirements
Python
Git
A code editor such as Visual Studio Code
Clone the starter repository
BashCopy
git clone https://github.com/MicrosoftDocs/mslearn-django-models-data
cd mslearn-django-models-data/starter
Note
BashCopy
code .
We'll follow the best practice of working with virtual environments for
our project.
BashCopy
# Windows
py -3 -m venv venv
.\\venv\\Scripts\\activate
# macOS or Linux
python3 -m venv venv
source ./venv/bin/activate
Install Django
The starter project uses a requirements.txt file to contain the list of all
necessary packages. We can install them by using pip.
In the same terminal window, run the following command to install the
required packages:
BashCopy
pip install -r requirements.txt
Django can host the application locally. We'll do this by using the built-
in terminal window in Visual Studio Code.
BashCopy
python manage.py runserver
Django was created for data-driven apps, so it's only natural that it
would have an integrated ORM. The Django ORM will feel natural to
Python developers, because it uses class syntax and inheritance that
you're already familiar with.
Models in Django
Completed100 XP
2 minutes
Create a model
If you wanted to create two models, Product and Category, you would
add two classes:
PythonCopy
from django.db import models
class Product(models.Model):
# details would go here
pass
class Category(models.Model):
# details would go here
pass
Add methods
Before we discuss how to configure the data for your model, it's
important to highlight the fact that a model is a Python class. As a
result, you can both add methods and override the ones
that Django.models.Model provides, or the ones inherent to all Python
objects.
PythonCopy
class Product(models.Model):
name = models.TextField()
def __str__(self):
return self.name
Add fields
Fields define the data structure of a model. Fields might include the
name of an item, a creation date, a price, or any other piece of data
that the model needs to store.
Different pieces of data have different data types, validation rules, and
other forms of metadata. The Django ORM contains a rich suite of
options to configure the fields of your models to your specifications.
The ORM is extensible, so you can create your own rules as needed.
The core piece of metadata for all fields is the type of data that it will
store, such as a string or a number. Field types map both to a database
type and an HTML form control type (such as a text box or a check
box). Django includes several field types, including:
To add fields to our Product and Category classes, we might have the
following code:
PythonCopy
from django.db import models
class Product(models.Model):
name = models.TextField()
price = models.DecimalField()
creation_date = models.DateField()
class Category(models.Model):
name = models.TextField()
Field options
You can use field options to add metadata to allow null or blank values,
or mark a field as unique. You can also set validation options and
provide custom messages for validation errors.
As with field types, field options map to the appropriate settings in the
database. The rules will be enforced in any forms that Django
generates on your behalf.
Field options are passed into the function for the field itself. Different
fields might support different options. Some of the most common are:
null
o Boolean option to allow null values.
o Default is False.
blank
o Boolean option to allow blank values.
o Default is False.
default
o Allows the configuration of a default value if a value for the field
is not provided.
o If you want to set the default value to a database null,
set default to None.
unique
o This field must contain a unique value.
o Default is False.
min_length and max_length
o Used with string types to identify the minimum and maximum
string length.
o Default is None.
min_value and max_value
o Used with number types to identify the minimum and maximum
values.
auto_now and auto_now_add.
o Used with date/time types to indicate if the current time should
be used.
o auto_now will always set the field to the current time on save,
which is useful for last_update fields.
o auto_now_add will set the field to the current time on creation,
which is useful for creation_date fields.
Note
The values null and blank can seem similar, but they mean different
things in database terms. null is the lack of a value, whereas blank is
specifically an empty value.
To add options to our models, the code might look like this:
PythonCopy
from django.db import models
class Product(models.Model):
name = models.TextField(max_length=50, min_length=3, unique=True)
price = models.DecimalField(min_value=0.99, max_value=1000)
creation_date = models.DateField(auto_now_add=True)
class Category(models.Model):
name = models.TextField(max_length=50, min_length=3, unique=True)
If you want to override this behavior, you can set the field that you
want to be your primary key. However, you should rely on
Django's id field in most situations.
PythonCopy
from django.db import models
class Product(models.Model):
name = models.TextField()
price = models.DecimalField()
creation_date = models.DateField()
category = models.ForeignKey(
'Category', #The name of the model
on_delete=models.PROTECT
)
class Category(models.Model):
name = models.TextField()
# product_set will be automatically created
By creating a model, you can define any essential fields and the
behavior of your data. Let's add the necessary models for
the dog_shelters application.
Create models
The first step in the process is to add the models. Django provides an
empty file named models.py that you can use for your models.
PythonCopy
# Create your models here
class Shelter(models.Model):
name = models.CharField(max_length=200)
location = models.CharField(max_length=200)
def __str__(self):
return self.name
class Dog(models.Model):
shelter = models.ForeignKey(Shelter, on_delete=models.PROTECT)
name = models.CharField(max_length=200)
description = models.TextField()
intake_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
We're also using ForeignKey in the Dog class. This part tells Django
there's a relationship between Dog and Shelter. By defining this
relationship, we're telling Django that every dog is related to a single
shelter.
3. Add the full path to the class name under the comment #[TODO] -
Add the app to the list of INSTALLED_APPS:
PythonCopy
#[TODO] - Add the app to the list of INSTALLED_APPS
'dog_shelters.apps.DogSheltersConfig',
PythonCopy
INSTALLED_APPS = [
#[TODO] - Add the app to the list of INSTALLED_APPS
'dog_shelters.apps.DogSheltersConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Adding the line to the INSTALLED_APPS list tells Django that this app
needs to be included when it runs the project.
Summary
You've now created two models for your Django application. Creating
models is the foundation to all Django projects.
The Django ORM goes beyond allowing you to interact with data. You
can also use it to create and update the database itself through a
process known as migrations.
Migrations
When we created our models and defined the fields, we also defined
the tables, columns, and relationships between those tables. We
created our schema definition by creating our models!
Migrations are used to create and update the database as our models
change. As you likely know, software is constantly changing. How we
define our models today might be different from how we define them
tomorrow. Migrations abstract the process of updating the database
away from us. We can then make changes to our models and use
Django to perform the necessary changes to the database.
Make a migration
BashCopy
python manage.py makemigrations
BashCopy
python manage.py sqlmigrate <app_label> <migration_name>
Note
The app_label part is the name of your app, typically the name of the
folder that contains your app. The migration_name part is the name of
the migration. You can also see the Python code for any app's
migrations in its migrations folder.
BashCopy
python manage.py showmigrations
Perform a migration
BashCopy
python manage.py migrate <app_label> <migration_name>
Note
The app_label and migration_name parts are optional. If you don't provide
either, all migrations will run. You'll use this command often during
development.
With our models created, let's create our database. We'll use the
default of SQLite and the tools available through Django.
BashCopy
python manage.py showmigrations
You'll notice a list of migrations. You might wonder why you have
migrations, even though you just started your application and haven't
made any. Django includes various tables for its user management
system, managing sessions, and other internal uses.
BashCopy
python manage.py makemigrations dog_shelters
After you run the command, you should see code that shows both
models stored as a migration in dog shelters.
The migrate command will run all migrations. In the case of SQLite, the
command will even create the database if it doesn't exist. Let's create
our database and perform the migrations.
BashCopy
python manage.py migrate
The migrations that the command runs include the one that we created
and the ones that are built in to Django.
Now that we completed the necessary setup for our SQLite database,
let's use the SQLite Visual Studio Code extension to explore the
created schema.
Note
You might get an error message about being unable to access the
SQLite core process. If this happens, you can install SQLite for
your operating system.
2. Open the command palette by selecting Ctrl+Shift+P on the
keyboard (or Cmd+Shift+P on a Mac).
1. Select db.sqlite3.
2. At the bottom of your workbench on the left side, select the arrow
next to SQLITE EXPLORER.
1. You can now see the list of all the created tables. Expand each one
to view the various columns.
If you explore your shelter and dog tables, you'll notice the
various columns that you created. These columns include id,
which is automatically created on each table.
Summary
Let's explore the API by working with the models that we created.
Django includes an interactive shell where you can run Python code in
the Django environment.
BashCopy
python manage.py shell
PythonCopy
from dog_shelters.models import Shelter, Dog
PythonCopy
shelter = Shelter(name="Demo shelter", location="Seattle, WA")
shelter.save()
The save part will write the object to the database. Because we
created this from scratch, it will execute an INSERT statement in
the database.
3. Create two new dogs for the shelter by running the following
Python commands in the shell:
PythonCopy
Dog(name="Sammy", description="Cute black and white dog",
shelter=shelter).save()
Dog(name="Roscoe", description="Lab mix", shelter=shelter).save()
Retrieving objects
PythonCopy
shelter.dog_set.all()
The dog_set part stores the list of all dogs for a particular shelter.
Django will return a QuerySet object with the two dogs that we
created.
BashCopy
<QuerySet [<Dog: Sammy>, <Dog: Roscoe>]>
The get function will return only one object. You can pass
parameters into get to provide a query string. Here we use pk,
which is a special keyword to indicate the primary key. The
returned result will be Sammy.
BashCopy
<Dog: Sammy>
PythonCopy
Dog.objects.filter(shelter__name='Demo shelter')
BashCopy
<QuerySet [<Dog: Sammy>, <Dog: Roscoe>]>
After you're done playing with the objects, you can close the shell by
running the exit() command.
Summary
You've now seen how you can programmatically work with data in
Django through the Django ORM.
Prerequisites
Software
o Visual Studio Code
o Git
Coding skills
o Understanding of HTML and CSS
o Basic understanding of Django
o Basic understanding of relational databases
o Intermediate-level knowledge of Python, including:
o Package management
o Virtual environments
o Inheritance
In this module, we'll work on a website for dog shelters. This project
focuses on collecting information on all existing dog shelters and the
dogs they hope to place across the United States. The fictional hope for
this app is that dogs would find suitable homes faster because they
would have individuals looking to adopt them from around the United
States and not just their local area.
Django is the perfect framework for this project. It provides a route for
quickly developing a customer-facing app. Django also provides an
established database and admin function that can easily be accessed
by employees for quick updating. We've created the initial setup for
this project, which allows us to focus on the concepts for this module.
Requirements
Python
Git
A code editor such as Visual Studio Code
BashCopy
git clone https://github.com/MicrosoftDocs/mslearn-django-admin-site
cd mslearn-django-admin-site/starter
Note
BashCopy
code .
We'll follow the best practice of working with virtual environments for
our project.
BashCopy
# Windows
py -3 -m venv venv
.\\venv\\Scripts\\activate
# macOS or Linux
python3 -m venv venv
source ./venv/bin/activate
Install Django
The starter project uses a requirements.txt file to contain the list of all
necessary packages. We can install them by using pip.
BashCopy
pip install -r requirements.txt
BashCopy
python manage.py migrate
Django can host the application locally. We'll do this step by using the
built-in terminal window in Visual Studio Code.
BashCopy
python manage.py runserver
Permissions for the admin site
Completed100 XP
4 minutes
Django includes a built-in admin site that can be used to manage the
data in your application and security. This site is part of the default
installation. As we'll see, it requires only a few lines of code to fully
activate it. Django also includes a full authentication and authorization
implementation, which you can use to control access to the admin site.
Django has three main types of users by default: users, staff, and
superusers. You can create your own types by making groups or
setting unique permissions.
Access levels
Expand table
Manage data No No
Manage users No No
By default, staff have access to the admin site but not to modify any
data. You can set individual permissions or create groups as needed to
provide the appropriate levels of access.
Create users
To create users in Django, you must first create a superuser. Use the
command createsuperuser from manage.py to create a superuser.
After you create a superuser, you can access the admin site to create
any other users.
Through the admin site, you can determine which users have access to
what data. Users can then use the admin site to add, update, and
delete items. They don't need to access the database directly or
bypass any of the validation rules you've implemented. The security
model and interface are already created for you as part of the
framework. All you need to do is activate your models so they appear
in the site, which requires only a couple of lines of code.
Create a superuser
BashCopy
# Windows
.\\venv\\Source\\Activate
# Linux or macOS
source ./venv/bin/activate
BashCopy
python manage.py createsuperuser
Note
After the admin user has been created, it's time for our first sign-in to
the Django admin interface. During the project setup earlier in this
module, we started the server, so our admin site is already active.
1. Go to http://localhost:8000/admin.
Select Users.
You'll now see the list of users, which includes the user you created.
4. Select SAVE.
5. On the next screen, select Staff status to make the new user a
staff user.
1. Select SAVE.
Register models
1. Open dog_shelters/admin.py.
PythonCopy
# Register your models here.
from .models import Shelter, Dog
admin.site.register(Shelter)
admin.site.register(Dog)
With our models registered, we can now manage our data. If there was
any data already in the database, we could modify it as needed.
Let's create a new Dog to explore how the admin site functions for data.
1. Notice that when you select the drop-down list for Shelter, no
shelters are listed because we haven't created one.
Note
The drop-down exists so that we can select the shelter into which
we would register the dog. We can create a new one by selecting
the plus sign (+).
2. Select SAVE.
The screen updates and shows the newly created Shelter as the
selected option for the dog.
4. Select SAVE.
The screen returns to the list of dogs, and the information on the
newly created dog appears.
1. If you select the dog, you'll be taken to the details page where you
can update any values or delete the entry.
Note
The display shows the name of the dog or the shelter if you go to
the Shelters portion of the admin site. This information appears
because we set the __str__ method on our objects. The default
display of any object is the value returned by __str__.
2. Select Users.
Select Choose.
1. Select SAVE.
Note
If you forgot the password, you can sign in as your superuser and
reset the password.
Notice that you can modify the dog, but not delete it.
Summary
In this module, we'll work on a website for dog shelters. This project
focuses on collecting information for all existing dog shelters and the
dogs they're hoping to place. The fictional hope for this app is that
dogs will be able to find suitable homes faster because they'll have
individuals looking to adopt them from around the United States and
not just their local area.
Requirements
BashCopy
git clone https://github.com/MicrosoftDocs/mslearn-django-views-
templates
cd mslearn-django-views-templates/starter
Note
BashCopy
code .
We'll follow the best practice of working with virtual environments for
our project.
BashCopy
# Windows
py -3 -m venv venv
.\\venv\\Scripts\\activate
# macOS or Linux
python3 -m venv venv
source ./venv/bin/activate
Install Django
The starter project uses a requirements.txt file to contain the list of all
necessary packages. We can install them by using pip.
In the same terminal window, run the following command to install the
required packages:
BashCopy
pip install -r requirements.txt
Django can host the application locally. We'll do this by using the built-
in terminal window in Visual Studio Code.
BashCopy
python manage.py runserver
Create a view
Loading data
You can use the Django ORM to load any data that you need from the
registered database.
The project that we're building has two models, Shelter and Dog. We
can load all objects or perform other queries by using the models that
we created. To load all shelters, for example, we would
use Shelter.objects.all(). We can load an individual shelter by
using Shelter.objects.get(pk=1).
Note
pk is a shortcut for primary key. You can use id and have the same
result, but using pk will ensure that the command works if you've
changed the property that represents the primary key to a different
name.
404 errors
Django's templating engine will take the HTML template that we build,
combine it with any data that we provide, and emit the HTML for the
browser. The helper function to perform this task is render.
The render function needs the object that represents the request, which
is the request parameter that we highlighted earlier. You also pass in
the name of the template, typically an HTML file that will reside in a
folder named templates.
Example
To create a view to display all shelters, you might use the following
code:
PythonCopy
def shelter_list(request):
shelters = Shelter.objects.all()
context = { 'shelters': shelters }
return render(request, 'shelter_list.html', context)
Register a path
Almost any web framework uses paths to process user requests. Paths
convert the portion of the URL after the name of the domain and before
the query string (which comes after the question mark) into a function
call.
PythonCopy
path('', views.index, 'index')
We can also create virtual folders for specific requests. For example, if
we wanted to list all shelters if someone requests /shelters, we could
use the following command:
PythonCopy
path('shelters', views.shelter_list, 'shelter_list')
URL parameters
PythonCopy
path('shelter/<int:pk>', views.shelter_detail, name='shelter_detail')
PythonCopy
def shelter_detail(request, pk):
# code
Create views
PythonCopy
from django.shortcuts import render, get_object_or_404
3. Below the line that reads from django.shortcuts import render, add
the following Python code to import your models:
PythonCopy
from . import models
4. At the end of views.py, add the following code to load all shelters,
create the context object for the template, and then render the
template for the user. This will become our list view for shelters
and the default page for our site.
PythonCopy
def shelter_list(request):
shelters = models.Shelter.objects.all()
context = {'shelters': shelters}
return render(request, 'shelter_list.html', context)
PythonCopy
def shelter_detail(request, pk):
shelter = get_object_or_404(models.Shelter, pk=pk)
context = {'shelter': shelter}
return render(request, 'shelter_detail.html', context)
2. Add the following code to register the paths for the two views that
we created:
PythonCopy
from django.urls import path
from . import views
urlpatterns = [
path('', views.shelter_list, name='shelter_list'),
path('shelter/<int:pk>', views.shelter_detail,
name='shelter_detail'),
# More patterns to come later
]
Django uses one core urls.py file as its URLconf. As a result, we need to
ensure that the one we created is properly registered.
1. Open project/urls.py.
2. Toward the bottom of the file, find line 17, which reads:
PythonCopy
from django.urls import path
At the end of the line, add , include. The new line 17 should now
be the following:
PythonCopy
from django.urls import path, include
3. Below the line that reads TODO: Register URLconf, add the following:
PythonCopy
# TODO: Register URLconf
path('', include('dog_shelters.urls')),
Important
Variables
The view passes variables into a template by using the render function,
which we'll explore in a later module. You can pass values and other
data to a template, including a QuerySet from the Django ORM. This
allows you to display data from the database for your application.
Filters
Filters are a great way to control how the data appears when it's
requested in a template. Because filters are already created, they
provide an easy way for you to format data without having to write any
special code.
For example, let's say we have to print out the names of the dog
breeds, and we want to make sure the first letter of every name is
capitalized.
HTMLCopy
{{ dog.name | capfirst }}
The variable is to the left of the pipe symbol ( |), and the filter is on the
right. This is just one of many filters that you can use to manipulate the
data when you're using Django template filters.
Tags
You can use tags to perform loops, create text, or provide other types
of commands for the template engine. Tags often resemble Python
syntax. But because they run inside the template (rather than inside
the Python interpreter), you'll notice some slight differences in syntax.
Without the ability to rely on tabs like we would with Python, each
block statement will require a corresponding end.
We can use if statements for Boolean logic, and for loops for iteration.
The core syntax for if statements looks like the following:
HTMLCopy
{% if dogs %}
<h2>There are {{ dogs | length }} ready for adoption!</h2>
{% else %}
<h2>We have no dogs ready for adoption. Please check back later!</h2>
{% endif %}
Note
Similarly, we can use a for loop to display the names of all dogs in a
list:
HTMLCopy
<ul>
{% for dog in dogs %}
<li>{{ dog.name }}</li>
{% endfor %}
<ul>
Template inheritance
Templates are used to generate the HTML that you want the user to
see while using your application. Pages in an application typically share
a common structure, where navigation might be on the left, a title is on
the top, and there's a consistent stylesheet. Django templates support
shared structures through inheritance.
HTMLCopy
<html>
<head>
<link rel="stylesheet" href="site.css">
<title>{% block title %}Shelter site{% endblock %}</title>
</head>
<body>
<h1>Shelter site</h1>
{% block content %}
{% endblock %}
</body>
</html>
HTMLCopy
{% extends "parent.html" %}
{% block title %}
Welcome to the Shelter site!
{% endblock %}
{% block content %}
Thank you for visiting our site!
{% endblock %}
When the page is displayed, it looks like the following:
HTMLCopy
<html>
<head>
<link rel="stylesheet" href="site.css">
<title>Welcome to the shelter site</title>
</head>
<body>
<h1>Shelter site</h1>
Thank you for visiting our site!
</body>
</html>
Notice how the placeholders are replaced by the content in the child
page.
Note
For this example, we used static text. As you'll see, you can also use
dynamic content.
HTMLCopy
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>{% block title %}Dog shelter site{% endblock %}</title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.
min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUF
pCjEUQouq2+l" crossorigin="anonymous">
</head>
<body>
<article class="container">
<section class="jumbotron">
<h3>Dog shelter application</h3>
</section>
{% block content %}
{% endblock %}
</article>
</body>
</html>
Note
We're using Bootstrap version 4.6 for our site. We don't need
Bootstrap knowledge here, though. We're using only one
class, jumbotron. Otherwise, we're using core HTML.
Notice the two {% block %} statements, one for the title and the next for
the content that the child pages will provide. We're providing a default
value for title, which ensures that we'll always have a title if a child
page doesn't set it.
We'll now create another template for listing all shelters. We'll loop
through the list of shelters and create links to details for all shelters.
2. Add the following code to create the template for our shelter list:
HTMLCopy
{% extends 'base.html' %}
{% block title %}
Shelter list
{% endblock %}
{% block content %}
<h2>Shelter list</h2>
<div>Here is the list of registered shelters</div>
{% for shelter in shelters %}
<div>
<a href="{% url 'shelter_detail' shelter.id %}">
{{shelter.name}}
</a>
</div>
{% endfor %}
</div>
{% endblock %}
We're also using a new tag, url. The url tag generates a URL
dynamically. Our URLs are registered in our URLconf, so they can
potentially change. By using the url tag, we can tell Django to retrieve
the appropriate URL from the URLconf rather than hard-coding in a
path.
The url tag looks for the name of the path, shelter_detail in our case,
and then the list of any expected parameters. shelter_detail has one
parameter, pk. That's the primary key, or ID, of the shelter. We specify
the ID by using shelter.id.
With our list template created, we can now create the detail template.
HTMLCopy
{% extends 'base.html' %}
{% block title %}
Shelter list
{% endblock %}
{% block content %}
<h2>{{ shelter.name }}</h2>
<div>Located in {{ shelter.location }}</div>
{% if shelter.dog_set.all %}
<div>Here is the list of available dogs</div>
{% for dog in shelter.dog_set.all %}
<div>
<a href="">
{{dog.name}}
</a>
</div>
{% endfor %}
</div>
{% else %}
<div>This shelter has no dogs available for adoption</div>
{% endif %}
{% endblock %}
Notice that in the body, we check to see if any dogs are inside the
shelter by using if shelter.dog_set.all. If there are dogs, we display
the list by using for to loop through all the dogs. Otherwise, we display
a message that says no dogs are available. We'll update the link in a
later unit.
Note
In this module, we'll work on a website for dog shelters. This project
focuses on collecting information on all existing dog shelters and the
dogs they hope to place across the United States. The fictional hope for
this app is that dogs could find suitable homes faster because they
would have individuals looking to adopt them from around the United
States and not just their local area.
Django is the perfect framework for this project. It provides a route for
quickly developing a customer-facing app. Django also provides an
established database and admin function that could easily be accessed
by employees for quick updating. We've created the initial setup for
this project, which allows us to focus on the concepts for this module.
Requirements
Python
Git
A code editor such as Visual Studio Code
BashCopy
git clone https://github.com/MicrosoftDocs/ms-learn-django-generic-
views.git
cd ms-learn-django-generic-views/starter
Note
BashCopy
code .
We'll follow the best practice of working with virtual environments for
our project.
BashCopy
# Windows
py -3 -m venv venv
.\\venv\\Scripts\\activate
# macOS or Linux
python3 -m venv venv
source ./venv/bin/activate
Install Django
The starter project uses a requirements.txt file to contain the list of all
necessary packages. We can install them by using pip.
BashCopy
pip install -r requirements.txt
Django can host the application locally. We'll do this step by using the
built-in terminal window in Visual Studio Code.
BashCopy
python manage.py runserver
The generic view system acknowledges this fact and provides classes
you can use that contain the core code already written. You inherit
from the appropriate class, set a couple of properties, and then register
an appropriate path in your URLconf. The rest is taken care of for you!
To create a detail view by using the generic view for a dog, you could
use the following code:
PythonCopy
from . import models
from django.views import generic
class DogDetailView(generic.DetailView):
model = models.Dog
template_name = 'dog_detail.html'
context_object_name = 'dog'
PythonCopy
path('dog/<int:pk>', views.DogDetailView.as_view(), name='dog_detail')
To create a view to display the list of all shelters by using the generic
view ListView, you could use the following code:
PythonCopy
from . import models
from django.views import generic
class ShelterListView(generic.ListView):
template_name = 'shelter_list.html'
context_object_name = 'shelters'
def get_queryset(self):
return models.Shelter.objects.all()
PythonCopy
path('', ShelterListView.as_view(), name='shelter_list')
We want to create a new detail page for dogs. We're going to use the
generic view DetailView to streamline the amount of code we need to
create.
Important
This exercise assumes that you've completed the setup steps earlier in
this module.
PythonCopy
# TODO: Import generic views
from django.views import generic
PythonCopy
class DogDetailView(generic.DetailView):
model = models.Dog
template_name = 'dog_detail.html'
context_object_name = 'dog'
1. Open dog_shelters/urls.py.
2. Underneath the line that reads # TODO: Register detail view, add
the following code to register the path for our DogDetailView.
PythonCopy
# TODO: Register detail view
path('dog/<int:pk>', views.DogDetailView.as_view(),
name='dog_detail'),
Important
Now you'll create the HTML template to display out the details of the
dog. The object name will be dog as we set that when creating the
form.
{% block title %}
{{ dog.name }}
{% endblock %}
{% block content %}
<h2>{{ dog.name }}</h2>
<div>About {{ dog.name }} - {{ dog.description }}</div>
{% endblock %}
With our path registered and template created, we can update the
shelter detail template to include links to our dog detail page.
1. Open dog_shelters/templates/shelter_detail.html.
2. Underneath the line that reads {# TODO: Add link to dogs #}, add
the following code to create a link for each dog to the detail view.
HTMLCopy
{# TODO: Add link to dogs #}
<a href="{% url 'dog_detail' dog.id %}">
{{dog.name}}
</a>
Like the code required to display data, the code to allow users to
modify data is repetitive. It can also be tedious because several steps
are required to ensure the data is valid and sent correctly. Fortunately,
the generic view system can streamline the amount of code we need to
enable this functionality.
Creation workflow
At the surface, the code to allow a user to create an item might seem
trivial. As it turns out, it's a deceptively involved process.
1. The user sends a GET request to signal they want the form to
create a new item.
2. The server sends the form with a special token to prevent cross-
site request forgery (CSRF).
3. The user completes the form and selects submit, which sends
a POST request to indicate the form has been completed.
4. The server validates the CSRF token to ensure no tampering has
taken place.
5. The server validates all information to ensure it meets the rules.
An error message is returned if validation fails.
6. The server attempts to save the item to the database. If it fails, an
error message is returned to the user.
7. After successfully saving the new item, the server redirects the
user to a success page.
This process requires quite a bit code! Most of it's boilerplate, which
means it's the same every time you create it.
Forms
CreateView
You specify the model and template_name you want to associate with it
just as you would with the other generic views. The key difference
for CreateView is the inclusion of a fields property where you list the
editable fields. By using this property, you can ensure fields that
shouldn't be edited, like a creation date, don't appear on the form. The
view to create a new dog might look like the following sample:
PythonCopy
from . import models
from django.views import generic
class DogCreateView(generic.CreateView):
model = models.Dog
template_name = 'dog_form.html'
fields = ['name', 'description', 'shelter']
UpdateView
PythonCopy
from . import models
from django.views import generic
class DogUpdateView(generic.CreateView):
model = models.Dog
template_name = 'dog_form.html'
fields = ['name', 'description', 'shelter']
PythonCopy
from django.db import models
# TODO: Import reverse
from django.urls import reverse
class Dog(models.Model):
# Existing code
def get_absolute_url(self):
return reverse('dog_detail', kwargs={"pk": self.pk})
DeleteView
PythonCopy
from . import models
from django.views import generic
from django.urls import reverse_lazy
class AuthorDelete(DeleteView):
model = Author
success_url = reverse_lazy('author-list')
Note
The generic views can create the HTML form for us dynamically. All we
need to provide is a template to act as the placeholder for the form.
The placeholder template ensures the form matches the rest of our
site. Fortunately, we don't need much code to create it.
The generic views automatically create a form variable for our template
to use. The form elements provided by Django can be displayed
inside <p> tags or as a <table>.
The form variable contains all of the appropriate HTML to create the
controls from the form. It doesn't contain the <form> tag itself or
a submit button. Our template must include four items:
The form element with the method set to POST because this setting
triggers the save operation on the server.
The code {% csrf_token %} to add the CSRF token to prevent
spoofing.
The code {{ form.as_p }} or {{ form.as_table }} to display the
dynamically generated form.
The submit button.
The following code can act as the host for any generic view form.
HTMLCopy
<form method="post">{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>
2. Add the following code underneath the line that reads # TODO:
Import reverse to import the reverse function.
PythonCopy
# TODO: Import reverse
from django.urls import reverse
3. Add the following code to the Dog class immediately the line that
reads # TODO: Add get_absolute_url to read the dog_detail path
from URLconf and pass the ID as the parameter.
PythonCopy
# TODO: Add get_absolute_url
def get_absolute_url(self):
return reverse('dog_detail', kwargs={"pk": self.pk})
Important
Create DogCreateView
PythonCopy
class DogCreateView(generic.CreateView):
model = models.Dog
template_name = 'dog_form.html'
fields = ['shelter', 'name', 'description']
Note
The order in which you list the fields will be the order that they'll be
displayed in the form.
With our view created, let's register the route in our URLconf.
2. Underneath the line that reads # TODO: Register create view, add
the following code to register the route.
PythonCopy
# TODO: Register create view
path('dog/register', views.DogCreateView.as_view(),
name='dog_register'),
HTMLCopy
{% extends 'base.html' %}
{# TODO: Register crispy_forms_tags #}
{% block title %}
Register dog at shelter
{% endblock %}
{% block content %}
<h2>Register dog at shelter</h2>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
We're adding a note for ourselves to add a library, which we'll do in the
next exercise.
Let's create a link on our shelter list page, which is currently the home
page for our application, to the register page we created.
HTMLCopy
{# TODO: Add link to registration page #}
<div>
<a href="{% url 'dog_register' %}">Register a dog available for
adoption</a>
</div>
3. Select Save.
textCopy
django-crispy-forms
BashCopy
pip install -r requirements.txt
3. Underneath the line that reads # TODO: Set template_pack, add the
following code to configure django-crispy-forms to use Bootstrap
4.
PythonCopy
# TODO: Set template_pack
CRISPY_TEMPLATE_PACK = 'bootstrap4'
HTMLCopy
{# TODO: Load crispy_forms_tags #}
{% load crispy_forms_tags %}
3. Replace the line that reads {{ form.as_p }} with the following code
to use the crispy filter.
HTMLCopy
{{ form | crispy }}
You'll see the page is now using Bootstrap for the form.
You've now updated your application so that the form uses Bootstrap.
In this module, you'll work on a website for dog shelters. This project
collects information about all dog shelters and their adoption-ready
dogs across the country/region. The fictional goal of this app is to find
suitable homes for the dogs quickly. The app reaches individuals who
want to adopt, not just in the shelters' local areas but across the
country/region.
Django is the perfect framework for this project. It allows you to quickly
develop a customer-facing app. It also provides an established
database and admin function that shelter employees can easily update.
We've created the initial setup for this project so you can focus on the
concepts for this module.
Requirements
Python
Git
A code editor such as Visual Studio Code
BashCopy
git clone https://github.com/MicrosoftDocs/mslearn-django-deployment
cd mslearn-django-deployment/starter
Note
BashCopy
code .
You'll follow the best practice of working with virtual environments for
this project:
BashCopy
# Windows
py -3 -m venv venv
.\\venv\\Scripts\\activate
# macOS or Linux
python3 -m venv venv
source ./venv/bin/activate
Install Django
The starter project uses a requirements.txt file to contain the list of all
necessary packages. You can install them by using pip.
BashCopy
pip install -r requirements.txt
Django can host the application locally. Set up the hosting from the
terminal pane.
BashCopy
python manage.py runserver
Introduction
Completed100 XP
5 minutes
For the front end, we want something that will allow us to integrate our
services without having to jump through a lot of hoops. A framework
like Flask is a perfect choice. Flask is described by its creators as a
"micro-framework", meaning it provides the core services required,
such as routing and templating, but otherwise allows you to use
whatever backend services your application needs. It's also
lightweight, making it quick to set up and deploy. We don't need a
database or anything fancy. We just need a framework to create our UI,
and be able to call the back-end service.
For the back end, rather than creating a machine learning model on
your own, you can use a collection of AI services (known as Azure
Cognitive Service). These services can either be accessed via an SDK
or an HTTP call. We can use the Translator service to meet our primary
goal of translating text.
In this module, we're going to explore Flask and the Translator service.
We'll see how we can create a web application to translate text into
various languages.
Learning objectives
In this module, you'll build a website using Flask and Azure AI services
to translate text.
Prerequisites
To get started writing our Flask application with Python, we need to set
up our development environment, which will require a couple of items
to be installed. Fortunately, the tools we'll use are relatively common,
so they'll serve you well even beyond this module. You might even
have them installed! We'll use these tools to develop and test your
application locally.
In this unit, you'll learn how to install Python tooling and create a
virtual Python environment. You'll install Flask, which is the framework
we'll use for creating the website.
Important
Install Python
To complete this unit, you must have Python 3.6 or later installed on
your computer. There's a chance you might already have Python
installed, especially if you've already used it. You can confirm whether
it's installed by executing one of the following commands:
BashCopy
python --version
If Python is installed, the output shows the Python version number. If
you need to install Python, follow the steps in the Install a Python
interpreter documentation for Visual Studio Code. You will also need to
install the Visual Studio Code Python extension.
Important
If you're using Windows, make sure that the folder location where you
installed Python is added to your PATH environment variable. If you
miss this step you'll receive an error message "Python isn't found",
even after performing the installation. To fix this, you would need to
follow these steps to add python to your PATH environment variable:
1. Find the directory with your python.exe file. You can type python
where in the command prompt terminal to locate the python.exe
file
2. Copy the path value "C:\<python path>", you will add it to
the Path variable in step 6
3. Click the Start menu and type Edit the system environment
variables, which opens up a System Properties window.
4. Under the Advanced tab, click on the Environment
Variables button.
5. Under the user variables, double click on the variable called Path,
which will pop up a window with a list of paths
6. Click New and paste in the copied path.
7. Once inserted, click Ok and Python should now be reachable from
any location in your computer
Note
BashCopy
# Windows, macOS or Linux
mkdir contoso
cd contoso
Important
Keep your command or terminal window open for the entirety of the
module.
BashCopy
# Windows, macOS or Linux
# Create the environment
python -m venv venv
BashCopy
# Windows
# Activate the environment
./venv/scripts/activate
# macOS or Linux
# Activate the environment
source ./venv/bin/activate
With our virtual environment created and activated, we can now install
Flask, the library we need for our website. We'll install Flask by
following a common convention, which is to create
a requirements.txt file. The requirements.txt file isn't special in
and of itself; it's a text file where we list the libraries required for our
application. But it's the convention typically used by developers, and
makes it easier to manage applications where numerous libraries are
dependencies.
BashCopy
code .
textCopy
flask
python-dotenv
requests
BashCopy
pip install -r requirements.txt
Note
You may receive an error message if your version of pip is not the
most recent. Follow the instructions on the error message to perform
the upgrade. The upgrade isn't required for this module.
Flask fundamentals
Completed200 XP
10 minutes
When a user uses a web application, they indicate what they want to
do, or the information they're seeking, by browsing to different uniform
resource locators (or URLs). They might type out an address directly
(say https://adventure-works.com), or select a link, or a button that
includes the appropriate URL. On an e-commerce site you might have
URLs that look like the following:
Methods or verbs
Note
A common application flow that uses GET and POST revolves around
using a form. Let's say we create an application where the user wants
to register for a mailing list:
As you might suspect, the user doesn't directly indicate the verb they
want to use, it is controlled by the application. Generally speaking, if
the user navigates to a URL directly, by typing it in or by selecting a
link, they access the page by using GET. When they select a button for
a form, they typically send the information via POST.
Note
A template allows you to write the core HTML (or a template) and
indicate placeholders for the dynamic information. Probably the most
common syntax for placeholders is {{ }}. Jinja, the templating engine
for Flask, uses this syntax.
HTMLCopy
<h1>Welcome, {{ name }}</h1>
Typically, the entry point for Flask applications is a file named app.py.
We're going to follow this convention and create the core of our
application. We'll perform the following steps:
Typically, the entry point for Flask applications is a file named app.py.
We're going to follow this convention and create the core of our
application. We'll perform the following steps:
1. If this exercise is your first time using Visual Studio Code to create
a Python application, you'll receive messages about installing the
Python extension and the linter pylint. Select Install to install
each of these add-ons.
PythonCopy
from flask import Flask, redirect, url_for, request, render_template,
session
app = Flask(__name__)
app will be our core application. We'll use it when we register our routes
in the next step.
Our application will use one route - /. This route is sometimes called
either the default or the index route, because it's the one that will be
used if the user doesn't provide anything beyond the name of the
domain or server.
PythonCopy
@app.route('/', methods=['GET'])
def index():
return render_template('index.html')
Jinja, the templating engine for Flask, focuses quite heavily on HTML.
As a result, we can use all the existing HTML skills and tools we already
have. We're going to use Bootstrap to lay out our page, to make it a
little prettier. By using Bootstrap, we'll use different CSS classes on our
HTML. If you're not familiar with Bootstrap, you can ignore the classes
and focus on the HTML (which is really the important part).
Important
2. Select the templates folder you created, and select New File to
add a file to the folder
HTMLCopy
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<link
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.
min.css" rel="stylesheet" integrity="sha384-
9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM"
crossorigin="anonymous">
<title>Translator</title>
</head>
<body>
<div class="container">
<h1>Translation service</h1>
<div>Enter the text you wish to translate, choose the
language, and click Translate!</div>
<div>
<form method="POST">
<div class="form-group">
<textarea name="text" cols="20" rows="10"
class="form-control"></textarea>
</div>
<div class="form-group">
<label for="language">Language:</label>
<select name="language" class="form-control">
<option value="en">English</option>
<option value="it">Italian</option>
<option value="ja">Japanese</option>
<option value="ru">Russian</option>
<option value="de">German</option>
</select>
</div>
<div>
<button type="submit" class="btn btn-
success">Translate!</button>
</div>
</form>
</div>
</div>
</body>
</html>
The core components in the HTML above are the textarea for the text
the user wishes to translate, and the dropdown list ( select), which the
user will use to indicate the target language. If you want to add more
languages, you can consult the list of supported languages for other
options. Set the value attribute to the language code, for
example, pl for Polish.
With our initial site created, it's time to test it! We're going to use the
integrated terminal inside Visual Studio Code to make our lives a little
easier.
BashCopy
# Windows
set FLASK_ENV=development
# Linux/macOS
export FLASK_ENV=development
BashCopy
flask run
Translation
100 XP
10 minutes
Translator service
Key management
To call Translator service (or any other Cognitive Service), we'll need a
key. This key will be used whenever we access the service. The key is
similar to a password. Anyone who has access to the key can call the
service, and if we were using a paid version they could run up a large
bill!
One great solution for protecting the key when doing development
work is to use a library called python-dotenv, commonly called dotenv.
When using dotenv, we create a file named .env, which contains
any key/value pairs we don't want as part of our source code. We'll
ensure that the file is listed in our gitignore file when we push our code
to GitHub, so that we don't accidentally publish it for the world to see.