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

Django With Python

Django with python

Uploaded by

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

Django With Python

Django with python

Uploaded by

Meera Desai
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 38

Django is a Web Application Framework which is used to develop web applications.

Django is a web application framework written in Python programming language. It


is based on MVT (Model View Template) design pattern. The Django is very
demanding due to its rapid development feature. It takes less time to build
application after collecting client requirement.

This framework uses a famous tag line:The web framework for perfectionists with
deadlines.

By using Django, we can build web applications in very less time. Django is designed
in such a manner that it handles much of configure things automatically, so we can
focus on application development only.

History
Django was design and developed by Lawrence journal world in 2003 and publicly
released under BSD license in July 2005. Currently, DSF (Django Software Foundation)
maintains its development and release cycle.

Django was released on 21, July 2005. Its current stable version is 2.0.3 which was
released on 6 March, 2018.

Django Version History

Version Date Description

0.90 16 Nov
2005

0.91 11 Jan 2006 magic removal

0.96 23 Mar newforms, testing tools


2007

1.0 3 Sep 2008 API stability, decoupled admin, unicode

1.1 29 Jul 2009 Aggregates, transaction based tests

1.2 17 May Multiple db connections, CSRF, model validation


2010

1.3 23 Mar Timezones, in browser testing, app templates.


2011
1.5 26 Feb 2013 Python 3 Support, configurable user model

1.6 6 Nov 2013 Dedicated to Malcolm Tredinnick, db transaction management, conn


pooling.

1.7 2 Sep 2014 Migrations, application loading and configuration.

1.8 LTS 2 Sep 2014 Migrations, application loading and configuration.

1.8 LTS 1 Apr 2015 Native support for multiple template engines.Supported until at leas
2018

1.9 1 Dec 2015 Automatic password validation. New styling for admin interface.

1.10 1 Aug 2016 Full text search for PostgreSQL. New-style middleware.

1.11 LTS 1.11 LTS Last version to support Python 2.7.Supported until at least April 2020

2.0 Dec 2017 First Python 3-only release, Simplified URL routing syntax, Mobile f
admin.

Popularity
Django is widely accepted and used by various well-known sites such as:

o Instagram
o Mozilla
o Disqus
o Pinterest
o Bitbucket
o The Washington Times

Features of Django
o Rapid Development
o Secure
o Scalable
o Fully loaded
o Versatile
o Open Source
o Vast and Supported Community

Rapid Development
Django was designed with the intention to make a framework which takes less time
to build web application. The project implementation phase is a very time taken but
Django creates it rapidly.

Secure
Django takes security seriously and helps developers to avoid many common
security mistakes, such as SQL injection, cross-site scripting, cross-site request
forgery etc. Its user authentication system provides a secure way to manage user
accounts and passwords.

Scalable
Django is scalable in nature and has ability to quickly and flexibly switch from small
to large scale application project.

Fully loaded
Django includes various helping task modules and libraries which can be used to
handle common Web development tasks. Django takes care of user authentication,
content administration, site maps, RSS feeds etc.

Versatile
Django is versatile in nature which allows it to build applications for different-
different domains. Now a days, Companies are using Django to build various types of
applications like: content management systems, social networks sites or scientific
computing platforms etc.

Open Source
Django is an open source web application framework. It is publicly available without
cost. It can be downloaded with source code from the public repository. Open source
reduces the total cost of the application development.

Vast and Supported Community


Django is an one of the most popular web framework. It has widely supportive
community and channels to share and connect.

Cmd

python --version

pip --version

Django-admin --version

pip install virtualenvwrapper

django-admin --version

mkdir projects

cd projects

django-admin startproject new

cd new

django-admin startproject projectname

django-admin startproject djangpapp

cd djangpapp
py manage.py runserver

localhost:8000/admin/

python3 manage.py createsuperuser

python3 manage.py runserver

1a Set up a virtual environment python -m venv env

1b Activate the virtual environment source env/bin/activate

2a Install Django python -m pip install django

2b Pin your dependencies python -m pip freeze > requirements.txt

3 Set up a Django project django-admin startproject <projectname>


4 Start a Django app python manage.py startapp <appname>
PART 1: FIRST STEPS

1. Create a project folder named films_project and go inside it.


mkdir films_project
cd films_project

If not mentioned otherwise, all the terminal commands from this


tutorial should be run inside the films_project directory.

2. Create a new virtual environment using the venv Python module.


I’m naming my virtual environment .myenv , but you can use another
name if you prefer.
python -m venv .myenv

3. Activate the virtual environment by running the correct command


for your chosen terminal and OS. The command below works in my
Git Bash for Windows. If you have doubts about activating virtual
environments with venv, please consult the Python documentation.
source .myenv/Scripts/activate

After activating it, you should see your virtual environment name
shown in the terminal, as in my example below:
Image by Author

From now on, all the commands must be run with your virtual
environment activated.

4. Install Django with PIP:


pip install django

5. Start a Django project called project itself.

IMPORTANT NOTE: don’t forget the dot at the end of this


command.
django-admin startproject project .

Running this command will create a manage.py file and a folder


called project with five files in it (counting the __init__.py one).
Thus, your films_project directory tree should look like this now:
Image by Author

Remember that .myenv is how I chose to name my virtual


environment folder, which is collapsed in the image above (there are
a bunch of folders and files inside it, which are not relevant for our
tutorial).

6. Start a Django application named films:


python manage.py startapp films

A Django project can have one or more apps. You can think of apps
in Django as a way of reusing code between different projects.

This command python manage.py will be frequently used in your


Django project, so get used to it. Also, running just python
manage.py in the terminal, without any other argument, will show
you the list of all its available options.

The startapp command above created a new folder called films with
some files and a folder inside it. Check them out:
Image by Author

The only file inside films_project/films/migrations is


a __init__.py one, showing that this migrations directory should be
used as a module in the future.

7. Every time we create a new app, we must add it to the list of


installed apps inside the settings.py file. Let’s do this now.
Open project/settings.py and add a string with the films app at the
end of the list saved in the INSTALLED_APPS variable. Don’t remove or
change any other string already in this list:
# inside project/settings.pyINSTALLED_APPS =
[ 'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles', #new value below:
'films.apps.FilmsConfig',
]

While settings.py is still open, you can change the default language
and timezone for the whole application in
the LANGUAGE_CODE and TIME_ZONE variables.

8. Run the code below to check for errors:


python manage.py check

If you received the message ‘System check identified no issues (0


silenced)’, that means that your application is ok. We are now ready
to start the local server and check our Django website for the first
time.

9. Run the command below to start the local server in the default
port (8000)
python manage.py runserver

Change the port if the 8000 one is already taken by another


application in your computer. Just add the new port number (8050,
for example) in the command:
python manage.py runserver 8050
10. Open your browser and go to one of the following address:
http://127.0.0.1:8000/

or
http://localhost:8000/

Exchange 8000 by your new port number, if necessary.

By accessing this server, which is running on your local machine,


you will see the Django default homepage for a new project.

Image by Author

11. Notice that a new file called db.sqlite3 was created inside
the films_project folder. That happened because sqlite3 is the
default database configured inside the project/settings.py file.
However, Django allows connections with many other databases;
you just need to make the correct configurations. We won’t talk
more about that now since such a topic is beyond the scope of our
current basic tutorial.

12. There is already another route created by Django for you. First,
be sure that your local server is running (that is, you executed python
manage.py runserver in the terminal and there are no error messages
there). Then go to the admin page and check it out:
http://localhost:8000/admin/

When you tried to access the link below, you probably saw a very
ugly error message, with the information ‘no such table:
django_session’ in the Exception Value field. I wanted you to see
that page because we can learn a lot from the error messages that
come on our way while programming. There is a very easy fix to this:
we only need to run the command to create in the database the
tables that the admin application uses. So:

13. Run the following command to create the database tables.


python manage.py migrate

About a dozen messages will be shown in the terminal console,


saying that the migrations were applied. That means that Django
created the necessary tables for the default applications in the
database, such as admin. Actually, if you use a sqlite3 service to
connect to the database and list all its tables, you would see these
new tables created by the migrate command you have just run.

14. You will also need to create a superuser to log in to the admin
area. Do that with the following terminal command:
python manage.py createsuperuser
Inform the user name, email, and password. Then, restart the server
with the python manage.py runserver , and use your information to
log in to the admin area. You’ll see the following page:

Image by Author

This is one of the many built-in resources that Django makes


available to the developer from the very start, and I wanted to let
you know that it exists, even though we won’t explore it now in this
tutorial. The admin area is one of Django’s powerful features, so it is
worth taking the time to learn how to use it.

PART 2: OUR FIRST ROUTES AND VIEWS.

15. Let’s create our first new route, which will replace the Django
default page we have just accessed. We will do that by modifying
the project/urls.py file. Notice that we are also adding a new import
statement to it.
# inside project/urls.pyfrom django.contrib import admin
from django.urls import path
from films import views # added
urlpatterns = [
path('', views.home, name='home'), # added
path('admin/', admin.site.urls),
]

16. If we run python manage.py check now, it will return an error


because your films/views.py is empty. Let’s correct that by adding
the following function to this file:
# inside films/views.pyfrom django.shortcuts import render
from django.http import HttpResponse # added
def home(request):
return HttpResponse('This is the home page.')

Now access http://localhost:8000 again to check how the new


modified page is displayed with the information we set in
the home view function:

Image by Author
Well done! It doesn’t look fancy at all, but we need to appreciate
what we have achieved here: we created our first webpage using
Django and Python, and all that writing just a few lines of code and
running a few commands in the terminal. Besides, all this
knowledge will help us to create much more complex and exciting
websites in the future, be sure of that. If we build our basis well
enough now, we can become very skilled Django developers in the
future, making great and helpful web applications and having fun
programming with Python at the same time.

At this point, it is interesting to make some brief considerations


about what Django considers as views. Unlike most MVC (Model-
View-Controller) frameworks, where the view refers to the front-end
part of the application, Django calls views the code where the
application logic and rules are configurated. The interface part in
Django is called template, which makes Django a MVT (Model-
View-Template) framework.

I will say it again: the views in Django are where we will create our
controllers, the application logic; it is not the front-end part (these
are called templates in Django). I mention it here because that point
confounds many people, especially those coming from the classical
MVC pattern.

As we can see from what we have done so far, the home function
in films/views.py is concise and straightforward; it just accepts a
Request object as its argument and returns a Response object that
writes a phrase in the DOM and displays it in the chosen URL. But
we could also pass HTML elements to the Response object in a view
function so that the browser would display them with different font
sizes and formats.

17. Let’s then modify the home function in films/views.py as follows:


# inside films/views.pyfrom django.shortcuts import render
from django.http import HttpResponse
def home(request):
# remove these print statements later
print('\n\nRequest object:', request)
print('Request object type:', type(request), '\n\n')

html_tags = '''
<h1>This is the Home Page</h1>
<h3>Thanks for visiting us</h3>
<p>MVT means:</p>
<ul>
<li>Model</li>
<li>View</li>
<li>Template</li>
</ul>'''

response = HttpResponse(html_tags) # remove these print


statements later
print('Response object:', response)
print('Response object type:', type(response))
print('\n\nUser-agent info :', end='')
print(request.META['HTTP_USER_AGENT'], '\n\n')

return response

If your Django local server is running, stop it with CTRL + C,

run python manage.py check to see if there is any error, and then start
the server again with python manage.py runserver. Next, go
to http://localhost:8000 and check the new webpage. Every time
you refresh this page, a GET request is sent to the Django server,
and the home function view is executed. You can check some
information about the Request and Response objects, which we
asked to be printed in the terminal console.
An important warning here: we will NEVER use strings with HTML
tags in our Django production code. Otherwise, we will submit our
application to XSS malicious attacks. So, we will just use HTML
inside Django views in these first examples. Later I will show you
how to use templates in Django to render HTML pages.

We will now create new routes to solidify what we have learned so


far.

18. Create the file films/urls.py.


touch films/urls.py

19. Add a new route in project/urls.py. It will serve as an entry point


for the routes we will create later for the films app.
# inside projects/urls.pyfrom django.contrib import admin
from django.urls import path, include
from films import views
urlpatterns = [
path('', views.home, name='home'),
path('admin/', admin.site.urls),
path('films/', include('films.urls')), # added
]

20. Fill the films/urls.py file with the new routes information.
# films/urls.pyfrom django.urls import path
from . import views
app_name = 'films'urlpatterns = [
path('', views.main, name='main'),
path('user_info/', views.user_info, name='user_info'),
]

21. Add the new view functions at the end of films/views.py :


# films/views.py(...)def main(request):
message = '<h1>This is the films MAIN page.</h1>'
return HttpResponse(message)def user_info(request):
message = '<h1>This is the films USER_INFO page.</h1>'
return HttpResponse(message)
22. Now visit the created routes and check if they are displaying the
correct messages:
http://localhost:8000/films/
http://localhost:8000/films/user_info

PART 3: MAKING THE VIEWS RENDER HTML


TEMPLATE FILES

It is now time to start using Django templates. For now, they will be
simple HTML files rendered by the view functions.

23. Create the necessary folders where the HTML files will be saved.

IMPORTANT: note that two of these new folders are


named templates: one is inside films, and the other one is directly in
the project root at films_project, at the same hierarchical level
of films.
mkdir templates
mkdir films/templates
mkdir films/templates/films

24. Create the following HTML files:


touch templates/home.html
touch films/templates/films/main.html
touch films/templates/films/user_info.html

25. Open project/settings.py , import the os module and, in the


variable TEMPLATES, fill the empty list in the TEMPLATES['DIR'] key,
with the following information (change just this one line and keep
the other ones):
TEMPLATES = [
{(...) 'DIRS': [os.path.join(BASE_DIR, 'templates')],(...)}
]
26. Put the following information inside the respective HTML files:

 templates/home.html:
<h1>This is the Home Page</h1>
<h3>Thanks for visiting us</h3>
<p>MVT means:</p>
<ul>
<li>Model</li>
<li>View</li>
<li>Template</li>
</ul>
<h3>Link to the website pages:</h3>
<ul>
<li><a href="{% url 'home' %}">Home Page</a></li>
<li><a href="{% url 'films:main' %}">Films Main Page</a></li>
<li><a href="{% url 'films:user_info' %}">Films User_Info
Page</a></li>
</ul>

 films/templates/films/main.html
<h1>This is the films MAIN page.</h1>
<h3>Link to the website pages:</h3>
<ul>
<li><a href="{% url 'home' %}">Home Page</a></li>
<li><a href="{% url 'films:main' %}">Films Main Page</a></li>
<li><a href="{% url 'films:user_info' %}">Films User_Info
Page</a></li>
</ul>

 films/templates/films/user_info.html
<h1>This is the films USER_INFO page.</h1>
<p>Username: Fabrício</p>
<h3>Link to the website pages:</h3>
<ul>
<li><a href="{% url 'home' %}">Home Page</a></li>
<li><a href="{% url 'films:main' %}">Films Main Page</a></li>
<li><a href="{% url 'films:user_info' %}">Films User_Info
Page</a></li>
</ul>

An important note here: if you visit the pages right now, you will
notice that nothing has changed. That happens because we haven’t
made any updates in our views. We need to make that each one of
views renders the correct template.

27. So, replace all content in films/views.py for the new code below:
from django.shortcuts import render
def home(request):
return render(request, 'home.html')def main(request):
return render(request, 'films/main.html')def
user_info(request):
return render(request, 'films/user_info.html')

Now visit the URLs and note the differences. Navigate through the
links to move quickly between pages.

PART 4: AVOID CODE REPETITION BY USING A BASE


TEMPLATE

I don’t know if you noticed it, but the code inside the HTML files has
many repeated lines. That is not desirable at all since it violates the
DRY (don’t repeat yourself) principle, and we need to fix that.
Django allows HTML code that should appear in multiple pages to
be written just in one HTML file, in a very easy way, using template
tags.

28. Create a templates/base.html file.


touch templates/base.html

We will now use some code from the Bootstrap web design
framework in our project. Unfortunately, I can’t explain here how
basic HTML, CSS, and Bootstrap code work. Otherwise, this tutorial
would be even more extensive than it already is. However, those are
really nice skills to learn if you want to work with web development,
even on the back-end side. New knowledge never hurts, in my
opinion.

So, if you want to know more about how to create nice webpages
interfaces, I suggest that you check out the great course
called Responsive Web Design Essentials — HTML5 CSS3
Bootstrap, by Daniel Walter Scott. The videos are very informative,
the exercises are great, and Daniel manages to transmit his
knowledge in a very effective and fun way.

29. Fill the templates/base.html file with the code below. This will be
the code that will be extended in the other HTML pages:

Please notice here the following new structures presented


in base.html:

 {% block head %} and {% endblock %};

 {% block content %} and {% endblock %};

 {% if title %} and {% else %} and {% endif %};

 {{title}}.

The notation {% %} is extensively used in Django templates language.


The {% block BLOCKNAME %} and {% endblock %} tags are used to mark
the points where the specific code blocks for each page in our
application will be inserted, using the base template.
The Django template language uses a lot of filters, which allow it to
execute functions and methods inside the templates. For example,
we have already seen the {% url %} filter in use in early stages of our
code: it receives a string as its argument, in the
form 'app_name:route_name', and it returns an absolute path for a
web resource. For example: {% url 'films:user_info %} will get the
route named user_info, inside the films app, and it will return its
path as a string and render it on the HTML page.

We can also notice that Django allows conditional statements inside


templates. As we will see later, for loops are also a possibility here,
which helps create more maintainable code.

Finally, notice the double curly brackets in {{title}}. This is the way
Django has to render Python variables passed by the views to the
templates. We haven’t done that yet, but we will later.

30. Replace the content for the HTML files as follows:

 templates/home.html:
{% extends 'base.html' %}{% block content %}<h1>This is the Home
Page</h1>
<br>
<h3>Thanks for visiting us</h3>
<br>
<p>MVT means:</p>
<ul>
<li>Model</li>
<li>View</li>
<li>Template</li>
</ul>{% endblock %}

 films/templates/films/main.html:
{% extends 'base.html' %}{% block content %}<h1>This is the
films MAIN page</h1>
<br>
<h4>Some Pixar Movies:</h4><ul>
{% for number in '012'|make_list %}
<li>Toy Story {{forloop.counter}}</li>
{% endfor %}
</ul>{% endblock %}

 films/templates/films/user_info.html:
{% extends 'base.html' %}{% block content %}<h1>This is the
films USER_INFO page</h1>
<br>{% if userinfo %}
<h4>username: {{userinfo.username}}</h4>
<h4>country: {{userinfo.country}}</h4>
{% else %}
<h4>username: not informed</h4>
<h4>country: not informed</h4>
{% endif %}{% endblock %}

Notice how each of these three last HTML files starts with {% extends

'base.html' %}, indicating that we are extending the template


information that comes from the base.html file. Moreover, the
HTML that we want to be displayed by each page is between the {%
block content %} … {% endblock %} tags, showing that we want it to
be inserted in the place from base.html where these tags are located.

Now look for errors with python manage.py check and then run the
server with python manage.py runserver. Check how more
presentable our pages are now.
Image by Author

PART 5: PASSING PYTHON VARIABLES TO THE


TEMPLATES

31. Now open films/views.py and replace the old code for this new
version. Then run the server and notice how that change impacted
the information displayed in the page’s title (the text meta
information presented in the browser tab) and in the user
information presented in the user_info page.

As we can see, the render() function can receive a dictionary (usually


named context or ctx) as its third argument. We can then access
these dictionary values by using just its keys without quotes.

Note, for example, how the title variable and its values appear both
in the views and in the base.html template conditional structure.
The home view function passes no title information, so the title value
will be None, and the else clause will be executed, showing the
default title on the home page. On the other hand, both the main and
the user_info views functions have a key 'title' in the context
dictionary, so its value will be ‘truthy’, and the if clause will be
executed, showing the title value in the tag browser when the
template is rendered.

Something similar happens with the userinfo variable, passed by


the user_info view function to the user_info.html template. Note also
that we will use a dot notation to access nested values, similar to
what is used in Javascript objects. If you try accessing values in
nested dictionaries with the context[key] structure from Python, it
will not work and an error will be raised.

PART 6: USE DJANGO MODELS TO CREATE YOUR OWN


DATABASE TABLES

32. Open films/models.py and insert the code below. We will create
our first Django models.

Notice that Django models are created as classes that inherit from
the models.Model Django class. We are creating here two
tables: genre and film, with actually 2 and 4 columns respectively.
We didn’t have to add the id column for each model in our code
because, in the project/settings.py file, the
variable DEFAULT_AUTO_FIELD is configured to create for every model
table an id column with auto-increment integer values.
Notice also that the Film model has a foreign key column
called genre, with a one-to-many relationship. That is not the perfect
relation between these two tables. Still, we are using here a more
simplified model for didactic purposes, since many-to-many models
are more complicated and should be learned in a second moment.

32. Run the python manage.py makemigrations to create the


migrations files that will set how these new two
tables film and genre have to be created by Django.

33. Now run the python manage.py migrate command to actually


create the two tables in the db.sqlite3 database, following the
instructions created in the last migrations. Their names in the
database will have the app name prepended to them, so the actual
tables names will be films_film and films_genre, if you want to run
some SQL code to check them out.

Now we are ready to populate these new tables we created. I will


show here two different approaches:

 using the admin area

 using the Django shell

34. Open films/admin.py and add the following code:


from django.contrib import admin
from .models import Film, Genre
admin.site.register(Film)
admin.site.register(Genre)
By doing that, we are making the Film and Genre models accessible to
the admin application.

35. Now go to http://localhost:8000/admin/, put the login


information from the superuser you created, and check how the two
new models appear on the screen:

Image by Author

36. Click on the Films link, find the Add Film button, fill in the fields
and save the information. You can add a new genre right on this
page by clicking on the green plus sign next to it. That will insert a
new row in the genre table. Save at least three new movies. I saved
the four Matrix movies, and you can see how their names are listed
nicely in the admin area. I can click on any of them, make changes to
their data and then press the save button. All these changes are
automatically persisted in the sqlite3 database for the Django
application.
Image by Author

37. Now stop the server and run python manage.py shell in the
terminal. The Django interpreter will then be open. This is another
really cool feature: it not only allows you to run Python code with the
interpreter, but it also has all your project files loaded. So, you can
run Django commands here using your project files, such as the
models we have just created.

I will use a few commands here from Django ORM. It allows us to


write Python code that runs queries in the database. The advantage
of using an ORM is that, if we ever want to change our database
connection to a MySQL or a PostgreSQL one, for example, we just
need to set the correct database configurations
in project/settings.py. All the queries using Django ORM (with
Python code) will remain the same, which is fantastic, in my
opinion.
38. Type the following commands in the Django shell we have just
initialized. That will create new Film and Genre objects, save them to
the respective tables and show a quick example of a SELECT query
for all films in the films_film table.

Image by Author

Now, we will use these new models we created and connect them to
our views so that the database data might be shown on our main
web page from the films app.

39. Inside films/views.py, import the Film model and change


the main view function. Keep the other views unaltered:

40. Open films/main.html and change its content to the code below.
Note how we use a for loop to show all films info saved in our
database.
{% extends 'base.html' %}{% block content %}<h1>This is the
films MAIN page</h1>
<br>
<h4>Films saved in our database:</h4><ul>
{% for film in films_list %}
<li>{{film.title}} ({{film.year}}, genre:
"{{film.genre}}")</li>{% endfor %}
</ul>{% endblock %}

Below is my screen after accessing http://localhost:8000/films. It


shows all the five movies I saved in my database (the four Matrix
movies and Finding Nemo).

Image by Author

This was just a brief example of how we can display information


from our database and send it to one of our pages. Actually, Django
has some customized views, built as classes, that we can use for
some of these most common tasks, such as listing all observations
(or part of them) on a webpage. This is done by
the django.views.generic.list.ListView class.
We will not discuss more about view classes in this introductory
tutorial. If you want more information about them, check
this Django documentation page.

PART 7: QUERY PARAMETERS

Up to now, we have only dealt with GET requests. When we have a


request with the GET method, we can pass parameters directly
appended to the URL, called query parameters. We will modify
the user_info view function to use these parameters as input to our
templates.

41. Make the following modifications in the user_info function


from films/views.py, keeping the other lines in the file.

In this new version, we have an if / elif structure where we check


the request method. We will not access the elif part yet, but I chose
to write it in the code already so that you can see how we could make
a view function run code depending on whether the request method
is either GET or POST. If we were using a class-based view, for
example, we would have two class methods ( .get() and .post()),
each one dealing with its respective request type.

I also want to call your attention to the


important request.GET attribute, which accesses a dictionary with all
the query parameters used in the URL.
42. Now, access the user_info URL and add the necessary query
parameters, as the example below:
http://localhost:8000/films/user_info/?username=Neo&country=USA

Note how a question mark is used to start writing query paraments.


Here we have two (username and country), with ‘Neo’ and ‘USA’ as
values, respectively. Furthermore, we can observe that the pair
query parameter name/value is separated by an equal sign, and the
ampersand (&) sign is used to separate the different parameters.

Go ahead and change the parameters’ values, hit enter, and see how
the values will change on the page. Check also the console to see how
the query parameters dictionary is structured. You can get any of its
values using the request.GET.get(KEY) code.

PART 8: HTML FORMS AND POST REQUESTS

Now let’s build an HTML form with a POST method.

43. Create the films/templates/films/user_form.html file and put


following HTML code inside it:

44. Make a minor change in the templates/base.html navbar by


adding a link to the new user_form page. I will not reproduce all
the base.html code here again; I will just present the extra <li> tag to
be added right before the closing </ul> tag:
<li class="nav-item active">
<a class="nav-link active" href="{% url 'films:user_form'
%}">UserForm</a>
</li>
45. Add a new route to films/urls.py.
from django.urls import path
from . import viewsapp_name = 'films'urlpatterns = [
path('', views.main, name='main'),
path('user_info/', views.user_info, name='user_info'),

## new route below ##


path('user_form/', views.user_form, name= 'user_form'),
]

46. in films/views.py, modify the imports and the user_info view, on


the one hand, and create the user_form view on the other. Since
much has been changed here, I present all the file code with its
modifications:

Let’s comment about this new films/views.py code in more detail.


When we access http://localhost:8000/films/user_form for the first
time, it will be a GET request, so the if clause in the view will be
executed, just loading the respective template. But when we fill in
the form fields and press the submit button, the POST method is
activated, and the code in the elif clause is run.

As I learned in Professor Charles Severance’s course, it is good


practice to send the data from a POST request to a different URL
than the one where the form is located. When we do that, a GET
request will be called to the new URL, and the POST data will be
lost.

So, before we move to the next page, we need to save the data passed
in the form. We do that by using request.POST.get(KEY) for every
input field, where KEY is the value from the name attribute from the
respective <input> HTML tag, so we cannot forget to set those. Then
we can pass these values to another dictionary located
in request.session, which is extremely helpful. It allows data to be
stored in the current browser session and be retrieved in different
moments by our code. That is why we can use, inside
the user_info view, the information saved in the session dictionary
and display them.

PART 9: ROUTE PARAMETERS AND DETAIL PAGES

47. Create a new route in films/urls.py. We will only show this line
below, but you already know how to insert it in the file.
(...)path('<int:id>/details', views.details, name='details')
(...)

Notice the new notation <int:id>. the < > signs here show we are
dealing with a new parameter type called route
parameter. int shows that it is an object from the int class
and id tells Django that a primary key is expected here.

48. Create the films/templates/films/details.html template with the


following content. We will use an HTML table structure with some
Bootstrap classes now.
{% extends 'base.html' %}{% block content %}<h1>Film
details:</h1>
<br><table class="table" style="width: 30%">
<thead>
<tr>
<th scope="col">Attribute</th>
<th scope="col">Value</th>
</tr>
</thead>
<tbody>
<tr>
<td scope="row">Title:</td>
<td class="text-dark">{{film.title}}</td>
</tr>
<tr>
<td scope="row">Year:</td>
<td>{{film.year}}</td>
</tr>
<tr>
<td>Genre:</td>
<td>{{film.genre}}</td>
</tr>
</tbody>
</table>{% endblock %}

49. Add the new details view in films/views.py. I commented out a


line of code that can also be used to query for just a single element
by id. Notice how the film id is passed as an extra argument to the
view.
def details(request, id):
film = Film.objects.get(id=id)
# other query option:
# film = Film.objects.filter(id=id)[0]
context = {'film': film}
return render(request, 'films/details.html', context)

50. Now choose a route


like http://localhost:8000/films/1/details and check this film info
details. Change the id number manually so you can see other films
details. If an unexisting id number is selected, an error will be raised
by the view since it does not have an error-handling code for this
kind of situation. So, if you find it interesting, search for ways to deal
with this kind of problem.

PART 10: USING PLOTLY GRAPHS WITH DJANGO

This part will be potentially useful for people who want to put
together these two amazing resources: Plotly graphs and Django.
The most important things to note here are the following:
 Use the .to_html() method from a Plotly Figure object and save it
in a context dictionary with a name such as fig.

 In the Django template, use the tag {{fig | safe}} to render the
graph.

I will use the Gapminder dataset here to speed things up. Since it
has nothing to do with films, it would be the proper procedure to
create another Django app. But I won’t do that. Instead, I will put a
new route outside the films one and borrow films/views.py to store
the view and auxiliary functions necessary to display the graph. I will
also use route parameters to filter the graph by year.

51. Open project/urls.py and add the new Gapminder route:


from django.contrib import admin
from django.urls import path, include
from films import views
urlpatterns = [
path('', views.home, name='home'),
path('admin/', admin.site.urls),
path('films/', include('films.urls')), # new route:
path('gapminder/<int:year>', views.gapminder,
name='gapminder'),
]

Inside films/views.py, we will add two functions that are not Django
views since they will not process an HTTP request. The
function get_data() only gets the Gapminder dataset
from plotly.express as a Pandas DataFrame. And create_plot() will
generate the famous Gapminder bubble chart. These functions are
called inside the gapminder function view, and the year route
parameter is used here to filter the dataset before generating the
graph.
52. Install Pandas and Plotly with PIP:
pip install pandas plotly

53. Open films/views.py, import Plotly Express and, right after the
last import, define the get_data() and create_plot() functions:
import plotly.express as px# keep the other imports(...)def
get_data():
df = px.data.gapminder()
return dfdef create_plot(df, year):
fig = px.scatter(
data_frame = df.query(f'year=={year}'),
x = 'gdpPercap',
y = 'lifeExp',
color = 'continent',
size = 'pop',
height = 500,
log_x=True,
size_max=60,
hover_name="country")

fig = fig.to_html()
return fig

54. At the end of films/views.py, create the gapminder view:


def gapminder(request, year):
df = get_data()
fig = create_plot(df, year)
context = {"plot": fig, "year": year}
template = 'gapminder.html'
return render(request, template, context)

55. create the file templates/gapminder.html and write the following


code in it:
{% extends 'base.html' %}{% block content %}<h1 class="text-
center">GAPMINDER (YEAR {{year}})</h1>
<div class="container-fluid d-flex justify-content-center">
{{plot | safe}}
</div>{% endblock %}
56. Access an URL with a year present in the Gapminder dataset
(such as http://localhost:8000/gapminder/2007) and play along with
your web page and its nice interactive graph.

You might also like