Getting Started with Django: First App – DEVELOPPARADISE
16/05/2018

Getting Started with Django: First App

This is the second article of the Django series. So far we have created a dummy project. In this article we will just not add some functionality to it but will also learn some more stuff about Django.

A few more things about Django:

We have talked about Django being an MVC framework. However, the controller in MVC is ‘view’ and view in MVC is called ‘template’ in Django framework. The view is actually the component which retrieves and manipulates data and templates present this data to the user. That’s why Django is more known as “Model-Template View or MTV” framework. Using another terminology does not change the fact of Django being an MVC framework neither affects the development of application. The difference between the two frameworks can be explained as follow.

Getting Started with Django: First App

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Knowing this, let’s start working with our app.

Views and URLs:

We saw the welcome page of our development server last time but it was too typical and the first thing that came into my mind was how can I change it. If you thought the same then don’t worry that’s exactly what we’re going to do. In order to do this, we will create an ‘entry point’ for our application. This entry point would be in the form of URL. This URL would tell Django to display our very own welcome message whenever user accesses this URL.

Creating the Welcome View:

Django defines view as a regular python function which would respond by generating corresponding page as per the request. To define our view, we first would have to create our Django application inside our project. Application is more like a module inside our web that would perform a certain task. You can think of it as a container for views and data models. To create the application, issue the following command within project folder (website folder that we created last time):

$ python manage.py startapp webapp

That’s pretty much same syntax that we used last time for project creation.

What this syntax does is it used startapp as the first parameter to python manage.py, and provided webapp as the name of our application.

App Exploration:

The above command will create a folder named webapp inside the project folder with the following files:

migrations:

Whenever we make a change in our data base for example create a table, define another field or drop a table, we would have to apply migrations to let Django know that we want these changes to happen. This folder would contain all those changes. Django migrations module is more than just a way of automatically generating and applying SQL statements, it’s also a transparent API to write your own database changes in Python. It comes with wheels for those who need it (or trust enough) and tools for those who like to get their hands dirty. We will experiment with migrations later.

__init__:

Same as the project creation, this file doesn’t contain any code and is there to tell Django to treat the folder whole as a package.

admin.py:

We already have talked about the admin panel. This file is used to display our models in Django admin panel. So whenever we are creating a new model, we would have to register it in this file.

The code that python created for us looks like this.

from django.contrib import admin  # Register your models here.

apps.py:

This file is created to help user include application configurations for the app.

from django.apps import AppConfig  class WebappConfig(AppConfig):      name = 'webapp'

basically it contains the meta data about our app.

models.py

Database contains tables to store our data. These models maps to a single table in database. Thus, a model is a single, definite source of information about our data. Whenever we are connecting to the database to store or retrieve data, we would do it in this file.

from django.db import models  # Create your models here.

tests.py

This file can be thought of a bug-killing tool. You can use this file to test a test suite, solve or avoid a number of problems.

from django.test import TestCase  # Create your tests here.

views.py

This file would control what user sees in our app.

from django.shortcuts import render  # Create your views here.

As we now have pretty good idea of the files for our app let’s go ahead and play with these.

Let’s create the main page view first. Open webapp/views.py in your text editor or IDE and add the following.

from django.http import HttpResponse  def main_page(request):     output = '''     <html>     <head></head>     <body>     <h1>%s</h1><p>%s</p>     </body>     </html>     ''' % (     'Hello World',     'Welcome to my first Application in Django',     )     return HttpResponse(output)

Let’s go through the code.

  • We import the class HttpResponse from django.http. As we are willing to generate a http response page so we need it.
  • We define a Python function that takes one parameter named request, build the HTML code of the response page, wrap it within an HttpResponse object and return it.

Django views work same as regular python function, It takes user input as parameter and return page output. Before actually seeing our added functionality into action we would have to connect it with URL.

Creating the URL:

We have talked about the urls.py file while discussing the project files. Go ahead, open it and edit it as follow.

from django.contrib import admin  from django.conf.urls import url  from webapp.views import *  urlpatterns = [      url('admin/', admin.site.urls),      url(r'^$', main_page),  ]

again let’s break down what we did.

  • The file is importing url from django.conf.urls.
  • We imported all the views from webapp.views.
  • The urlpatterns function is used to define the URL table. It contains two mapping for now — one was already created for us; admin; second from r’^$’ to our view main_page.

There are two things to note about our defined url. It is a raw string that contains two characters, ^ and $. Python’s way of defining raw string is r ‘’. By raw we mean that anything between r ‘’; even if contains any escape sequences or backslashes; would be retained rather than interpreted in any other way. This is important because regular expressions often contain backslashes. Other is the format of our regular expression. In Django, urls are defined as regular expressions. In regular expressions, ^ means the beginning of the string, and $ means the end of the string. So ^$ basically means a string that doesn’t contain anything; that is an empty string. Given that we are writing the view of the main page, the URL of the page is the root URL, and indeed it should be empty.

Now that everything is set, let’s run and check our first view. Launch the development server. You can either launch it from command prompt by entering the following command.

$ python manage.py runserver

or just run your application from inside the IDE which will automatically run the server for you. Do as you please. Now go to http://127.0.0.1:8000/ to see the page generated by the view.

Getting Started with Django: First App

 

 

 

 

 

 

 

 

Congratulations! Your first Django view is up and running.

Let’s explore what’s going on behind the scene.

  • When you navigate to http://127.0.0.1:8000/, Django searches the URL table in urls.py for a URL that matches the request.
  • If Django found the URL, it calls its corresponding view. The view, then returns the generated page wrapped in an HttpResponse object.
  • If Django doesn’t find the URL, it will simply display a 404 ‘page not found’ error.

Our main page is simple at the moment and html is also embedded in between the python code. But what if you are working for a company and your co-worker is designing the website whereas you just have to implement that design. Here’s another catch you co-worker just knows html and python is an ‘Alien’ language for him. What would you do in that case? It means this approach is not good enough.

  • Good software engineering practices always emphasize the separation between UI and business logic, because it enhances reusability. However, embedding HTML within Python code clearly violates this rule.
  • Editing HTML embedded within Python requires Python knowledge, but this is impractical for many development teams whose web designers do not know Python. (The scenario we discussed last time.)

Getting Started with Django: First App

Yeah this could be you with HTML embedded in python

  • Handling HTML code within Python code is a tedious and error-prone task. For example, quotation marks in HTML may need to be escaped in Python string literals, and the overall result may be unclean and unreadable code.

It means we would have to separate our HTML code from python code. Django provides a component that will help us accomplishing this task; it is called the template system. Let’s apply it to our welcome page and see how it works.

First of all, create a separate folder called templated in your project folder. This is just to keep our directory structure clean. Fun thing is if you’re using Pycharm then you can see this templates folder already created for you. It’s just not created but also its path is already added in seetings.py. If you’re creating your own template folder then you need to inform Django about it. Open settings.py, look for the TEMPLATE_DIRS variable and add the absolute path of your template folder to it. Or if you don’t want to hard-code the path into settings.py then use the following code:

import os.path  TEMPLATE_DIRS = (  os.path.join(os.path.dirname(__file__), ‘templates’),  )

What it simply does is that it informed Django where to look for template. Now let’s move to our HTML part. Create a file called index.html in the template folder and edit it with the following content.

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Welcome Page</title> </head> <body> <h2>Hello World</h2> <p>Welcome to my first Application in Django</p> </body> </html>

Pretty straight forward HTML code. All it does is display the same welcome message we did last time but this time without any python code. Let’s see how to view this template in the view. Edit webapp/views.py file as follow:

from django.shortcuts import render  def main_page(request):      return render(None, 'index.html')

That’s right. All we need is three lines of code.

  • We imported render method from django.shortcut.
  • We just defined the view using main_page as its name and passing request object to it.
  • In order to create HTML output from the template, we used the render method. It combines a given template with a given context dictionary and returns an HttpResponse object with that rendered text.

As per the documentation, render function is somewhat like this.

render(request, template_name, context=None, content_type=None, status=None, using=None)

let’s break down the structure of this function. It has some required and some optional arguments.

Required Arguments:

request:

The request object used to generate this response. In our case, we are just displaying a static HTML page so we used request=None.

template_name:

The full name of a template to use or sequence of template names. If a sequence is given, the first template that exists will be used. We named our template as index.html so we used its name as argument to our function.

Other arguments are all optional but let me explain them too.

Optional arguments:

context:

A dictionary of values to add to the template context. By default, this is an empty dictionary. It means that it won’t make any difference if you call the function with an empty dictionary as render(None, ‘index.html’, {}) or without it. But if a value in the dictionary is callable, the view will call it just before rendering the template.

content_type:

The MIME type to use for the resulting document. Defaults to the value of the DEFAULT_CONTENT_TYPE setting.

Status:

The status code for the response. Defaults to 200.

Using:

The NAME of a template engine to use for loading the template.

Enough of the explanation. Now run the server and you should see the exact screen you saw last time.

Getting Started with Django: First App

 

 

 

 

 

 

 

 

And Boom!

Now you have your HTML code separated from python. But that’s the static page. Is that all by Django? What if I want to integrate some variables on my page? Django does support variable integration. Variables are surrounded by a pair of curly braces {{ }} like this. Let’s see how it works.

Open your index.html file and replace the code as follow:

<!DOCTYPE html> <html lang="en"> <head> <title>{{ head_title }}</title> </head> <body> <h1>{{ page_title }}</h1> <p>{{ page_body }}</p> </body> </html>

The structure of this template is very much similar to the one before. Just a small difference however; we used the special syntax for variable support to indicate the sections we want to change in our view.

Now open views.py and edit its content as follow:

from django.shortcuts import render  def main_page(request):     return render(None, 'index.html', {'head_title': 'Welcome Page',                                        'page_title': 'Hello World',                                        'page_body': 'Welcome to my first App in Django.'})

We talked about the render’s optional argument context. In the above code, we just used that argument and loaded the page as per our context.

You can use it to pretty much display anything. For example:

My first name is {{first_name}} and my last name is {{last_name}}. 

With a context of

{‘first_name’: ‘Mehreen’, ‘last_name’: ‘Tahir’}

this template renders to ‘My first name is Mehreen and my last name is Tahir’

Template Tags and Filters:

Django comes along the whole template system. The mains of this system are variables and tags. We have seen the variables so let’s talk about the Tags.

Tags:

Tags provide arbitrary logic in the rendering process. They are surrounded by {%  %} and can be used to output content or as control structure. As

{% if today_is_weekend %}      <p>Welcome to the weekend!</p>  {% else %}      <p>Get back to work.</p>  {% endif %}

Or.

{% comment %}  This is a  multi-line comment.  {% endcomment %}

Or

{% block %}  This text can be overridden by child template by using the same block tag.  {% end block %}

It could also be:

{% csrf_token %}

You’re going to use this special template tag when dealing with forms. It provides easy-to-use protection against Cross Site Request Forgeries.

Also

{%extends %}

This tag is use to inherit from a base template.

Filters:

Filters are an effective way to modify the data before sending it to the template. Like this:

{% filter lower %}      This text will appear in all lowercase.  {% endfilter %}

An upper filter can also be used:

 {% filter upper %}      This text will appear in all lowercase.  {% endfilter %}

There are a lot of cool filters like capfirst, pluralize, linebreaks etc. or maybe use something like this.

{{ value|add:"1" }}  # If value is 2, then the output will be 3.

This is just the glimpse of powerful tag system of Django. You are free to experiment with it.

Django Models

Our site just contains the static data for the moment. But where’s the fun in it. Let’s take the site a step ahead; may be store data so as to automate all the tasks; so let’s look into database schema.

Django proposes database access with an abstraction layer called Object-Relational Model (ORM). This allows you to use the python implementation object in order to access the data so you don’t have to worry about How to use database. With ORM, we don’t need to use the SQL query for simple and slightly complex actions. But how to work with ORM? That’s where models come in handy. You can say they simply create a link between our views and database.

Models:

A model is pretty much just an object that inherits from Model class. This Model class is specifically designed and provided by Django for the sake of data persistence. Think of model as a table in the database and the properties we define for our model will map the fields in the table.

In this article, our main focus would be:

  • set up and access database
  • database migrations
  • creating simple models
  • defining relationship between models
  • using administration module

Database setup:

Open settings.py and scroll all the way down to the DATABASES. You should see this:

DATABASES = {     'default': {         'ENGINE': 'django.db.backends.sqlite3',         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),     } }

Let’s see what it says:

  • The ENGINE property specifies the type of database to be used.
  • The NAME property defines the path and final name of the SQLite database.

These are the default settings for our project. You are more than welcome to get your hand dirty and configure any other database (Django does support them all) but for the sake of simplicity, I’m going to stick with the default settings.

Migrations:

Migrations are Django’s way of transmitting changes (like creating a field, deleting a model etc.) that you make to your models. Whenever you create a model or do some changes to it, you need to tell Django to make the changes in your database by applying migrations. But what if we don’t apply them? 

While running your app, you would have noticed somewhat like this.

You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.

Let’s try something, run your application and navigate to http://127.0.0.1:8000/admin/. Oops! You’re going to run into an error.

Getting Started with Django: First App

What just happened?

Remember I talked to you about built in admin panel. We just tried to access that but here’s a catch. Django does not know that we want that functionality in our app. Why? Because we haven’t applied any migrations and so that table is not being created in our project. Let’s apply migrations and see what happens.

Enter the following command (you should be in your project directory.)

$ python manage.py migrate

and you’ll see a screen saying that all those migrations are being applied.

Getting Started with Django: First App

 

 

 

 

 

 

 

 

 

 

 

Run your app again and try to access admin panel. This time you’ll see a login page instead of error. But we can’t login because we haven’t set any admin user. We’ll get back to admin user part but let us first create a few more models.

Creating simple models:

Let’s just say we want to make our site to be the Tasks manager application. For this sake, we need a user who saves the tasks performed on a project. We need to create two models: UserProfile and Project. Open webapp/models.py file. It looks like this.

from django.db import models   # Create your models here

The above line of code allows us to import base model of Django. Now all we need to do is to define our very own models.

UserProfile model:

To create the UserProfile model, what data you think we would need to keep. It could be user’s real name, username, password, phone number etc. Let’s create the model and see the rest.

Enter the following in your models.py file.

class UserProfile(models.Model):      name = models.CharField(max_length=50, verbose_name='Name')      username = models.CharField(max_length=25, verbose_name='User name')      password = models.CharField(max_length=25, verbose_name='Password')      phone = models.IntegerField(max_length=12, verbose_name='Phone number')      birth_date = models.DateField(verbose_name='Birth Date')      email = models.EmailField(verbose_name='Email')

In the preceding code, our UserProfile is inheriting from Model class. We also added a few attributes inside the class and specified the values. As for our first field, name is a character string type with a maximum length of 50 characters. verbose_name property defines the human readable names of our fields. You can also say that these will be the labels that defines our field in the form later.

Project model:

For our project model, we will require the title, description and client name.

Use the following code to define project model.

class Project(models.Model):      title = models.CharField(max_length=50, verbose_name="Title")      description = models.CharField(max_length=1000, verbose_name="Description")      client_name = models.CharField(max_length=1000, verbose_name="Client name")

for now, we have two models, UserProfile and project but we haven’t defined any relation between them so we don’t know which project is related to which user. For this purpose, let’s define another model task as follow.

class Task(models.Model):      title = models.CharField(max_length=50, verbose_name='Task Title')      project = models.ForeignKey(Project, verbose_name='Project', on_delete=models.CASCADE)      app_user = models.ForeignKey(UserProfile, verbose_name='User', on_delete=models.CASCADE)

We defined two foreign keys in this model, project and app_user. What these will do is contain the details of the record to which they are attached in the other table. Before seeing this all in action, we need to first add our app in installed apps. Open settings.py and add the name of your app (webapp in this case) in INSTALLED_APPS.

INSTALLED_APPS = [      'django.contrib.admin',      'django.contrib.auth',      'django.contrib.contenttypes',      'django.contrib.sessions',      'django.contrib.messages',      'django.contrib.staticfiles',      'webapp.apps.WebappConfig'  ]

Next apply migrations by entering the following commands.

$ python manage.py makemigrations

This command is responsible for creating new migrations. You should see following message appearing on your screen.

webapp/migrations/0001_initial.py

    – Create model Project

    – Create model Task

    – Create model UserProfile

    – Add field app_user to task

    – Add field project to task

Now enter the following command.

$ python manage.py migrate

You should see this message after the command is executed.

Applying webapp.0001_initial… OK

All done!

But wait a second what is it webapp.0001_initial? If you see your project directory once again, a file naming 0001_initial.py is created under webapp/migrations which is nothing but pretty much a projection of your created model but with migrations being applied. This is one of the coolest features that Django offers that it keeps the history of your migrations. Now if you create some other models or make some changes a second file would be created under the same tab. If anything goes wrong at any point, you cans simply look it up and you don’t have to do anything extra. Sweetness overloaded.

Also notice that you didn’t have to execute even a single query of SQL. Django did that for you. If you want to check that just execute the following command.

$ python manage.py sqlmigrate webapp 0001

and you’ll see all the SQL queries that are executed behind the back.

Admin Module:

So far so good but how to see these models in the database? Seems like it’s time to continue with our admin user. Run the following command to set up the admin.

$ python manage.py createsuperuser

It will ask you for username, email and password. Enter your desired credentials and you’re good to go.

One last thing before you see things in action. You need to register your models with admin. Open webapp/admin.py file and enter the following snippet.

from django.contrib import admin  from .models import *   admin.site.register(UserProfile),  admin.site.register(Project),  admin.site.register(Task),

Now try accessing the admin panel again at http://127.0.0.1:8000/admin and login using the credentials you set. You should see your models (UserProfile, Project and Task) under webapp.

Getting Started with Django: First App

You’re free to populate it with some random data for testing purposes or to play around. But fun’s not over yet. What if a user comes to our site and wants to save some data?  We’ll see that in the next article.