Develop your first web application in Django 1.10 — Part 1
In part 0 I discussed initial installation and configuration. Now it’s time to get into the code. The things I am going to do in this post are:
- Understanding the concept of Project and Apps in Django world.
- Creation of App.
- Using templates to create home page.
Projects vs Apps
Django offers a very useful modular approach of creating web applications. Unlike other frameworks like PHP Laravel or Rails, Django let you create multiple apps under a project. This idea might look alien to those coming from the background of other frameworks where a project == app and you need to rely on routes etc to divide functionality. Let me take example of my own website.
If you look at it, it contains a few static pages like Profile, Services, Testimonials etc and a couple of dynamic sections: Blog and Projects. If you are working on Rails or Laravel, you might come up with a group route to group relevant routes. This might work for task but what if you want to add a blog in another project, now you have no choice other than copy pasting code and manage accordingly, pretty boring right? Django provides you following project structure:
I can now plug in as many apps as I want under a single Project (e.g: My Home Page) and Django will itself take care of the respective URLs of the app under a project. It is not necessary that you can only add your own app, you can incorporate any 3rd party app within your project and use it on your own.
App Creation
It’s time to create the app. I will name this app as tracker. Go to your newly created project folder, in my case ohbugztracker
and run the following command:
./manage.py startapp tracker
Once it’s run it will create a new folder tracker
and now your project directory will look like this:
You can things like migrations
, admin.py
, models.py
and views.py
.
The app is created but Django is still not aware of it, you will need to perform a couple of actions now. First, go to settings.py
file and under INSTALLED_APPS
section add your app entry for installation purpose. It will then look like this:
INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘tracker’,
]
And creation of urls.py
file in tracker
app folder.
from django.conf.urls import url
from . import viewsurlpatterns = [
url(‘^$’, views.index, name=’index’)
]
Don’t get scared as I will be explaining what does it all mean.
OK so I installed my newly created app by adding into INSTALLED_APPS
list and created urls.py
. Let’s run the server and see how it goes. I run the server by running ./manage.py runserver
and now visit: http://127.0.0.1:8000/tracker
Ouch! what’s that! Why am I seeing this! Wait! I forgot one thing. I did create urls.py
under tracker
folder but I did not add entry of it in main urls.py
. No worries, there’s always a second chance. Go to main urls.py
, in my case in ohbugztracker\urls.py
from django.conf.urls import url, include
from django.contrib import adminurlpatterns = [
url(r’^admin/’, admin.site.urls),
url(r’^tracker/$’, include(‘tracker.urls’)),
]
here I imported include
first and then add the entry. It should work, right? Wrong! because now server is not starting and giving error:
url(‘^tracker/$’, views.index, name=’index’)AttributeError: module ‘tracker.views’ has no attribute ‘index’
Fair enough as I have not added index
method in views.py
. Before I do it, let me exaplain what is happening.
As I mentioned in the diagram above, Django lets you add multiple apps under a project or I say under a domain(example.com). When you do something like:
url(r’^tracker/$’, include(‘tracker.urls’)),
You are telling server that when someone visits a URL http://127.0.0.1:8000/tracker, Django will try to match possible pattern, if found, it will include respective app.urls file. In our case it is tracker.urls.
If you notice, Django let you use RegEx to define your URLs pattern. Now let’s try again
Now open views.py
file and add the following:
from django.shortcuts import render
from django.http import HttpResponsedef index(request):
return HttpResponse(‘<h1>I am the root of Tracker App<h1>’)
Here I imported HttpResponse
and add a view method index
which is responded a string in return. If you are a Laravel, Rails or any other MVC user, you might be surprised that why is it being called a View rather than a Controller. Here is a good explaination that Django is not an MVC framework but an MTV (Model Template View) framework. Now try again and you should see something like:
Cool! so we created and installed our new Django App and created a view method which displays text on visiting the application URL.
Before I move further, I will make a small change in my route file. Usually each app has it’s own unique url prefix, tracker in our case which helps to differentiate from other installed apps. Since there is only one app in our case, I will make a change in main urls.py
file. Go to main urls.py
and change the following from:
url(r’^tracker/$’, include(‘tracker.urls’)),
to
url(r’^$’, include(‘tracker.urls’)),
What actually I did, instead of making one to visit http://127.0.0.1:8000/tracker to visit the only app, I just made it available on root URL. So now when I go to http://127.0.0.1:8000/ I will be seeing same page as you see above. Much better, right?
Tired, No? Good! Now just move to next step and integrate the markup of home page in our app.
Templates in Django
Like other web framework Django provides facility of Templates which not only helps to organize the presentation layer but also to avoid redundancy of the markup. I will discuss it further in next part, for the time being just bring our required HTML in the app.
First off, add the templates
folder under your app folder tracker
. Why templates
folder? Well I just set this in main settings.py
under TEMPLATES
DIRS
key.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
If you want, you may change it, I will go with the convention suggested by Django. Now go to templates
folder and add another folder, named as layouts
and add a file master.html
in newly created layouts
folder. In this file I am just dumping all the markup of HomePage of my application.
In next step add another html file under templates
folder and call it index.html
and add the following line in it. Don’t worry I will explain it later in detail. Your folder structure should look like this:
{% extends “layouts/master.html” %}
Add the above line in index.html
file, it tells that the file *inherits* the markup from master.html
file.
Go to views.py
file and make following changes:
from django.shortcuts import renderdef index(request):return render(request, ‘index.html’)
Now I am using render
method which accept request
as first parameter and template file as a second parameter. If all goes well, you should be able to see the following:
In case you wonder why this all looking quite stylish, the reason is I am calling bootstrap from the CDN and since my own css files are not included it is just showing everything out of proportion at the moment. Later I will be calling all css/js files from local machine. I will be covering it in next post.
The Github repo has been updated for this project.
This post originally published here.