Introduction to Web Development with Django

This is an abridged version of the Django Girls Tutorial

This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit https://creativecommons.org/licenses/by-sa/4.0/

Django Installation

First, we need to create a directory for our site to live in. then we need to create a python virtual environment which will contain the packages we need.

$ mkdir django
$ cd django
$ python3 -m venv venv
$ source venv/bin/activate

The last line will set up our python to use the virtualenv we just created.

Now we can install the python package we will need.

$ pip install django

Your first Django Project!

With our shiny new version of django, we get the command django-admin which will create a project for us.

django-admin startproject mysite .

This gave us a skeleton project, with basic default settings, and the very usefull manage.py script which will be used to help us develop the site. We can use this default setup to create a SQLite databse.

python manage.py migrate

We now have a working web app! We can run a development server.

python manage.py runserver

You can visit it in your browser by going to localhost:8000

Django Models

Django uses an Object Relational Mapper (ORM) to make working with databses easy. An ORM is a mapping between database rows and python classes. So you can read a row from a databse, and instantiate a python class using the data, then work with the class in python. When you are done, you can save the state of the class to the database.

Create an Application

$ python manage.py startapp blog

Add it to the installed apps in settings

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
]

now create a model by opening blog/models.py

from django.conf import settings
from django.db import models
from django.utils import timezone


class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    text = models.TextField()
    created_date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.title

Now that we have the python part of the ORM, we need the database side. Luckily, Django is smart enough to create, modify, and delete everything it needs to in the databse using migrations. Let's create and execute our first migration

$ python manage.py makemigrations
python manage.py migrate

Django Admin

Django comes with an amazizng admin interface for our apps, it allows us to perform all the backend management of our database.

from django.contrib import admin
from .models import Post

admin.site.register(Post)

We have to register a superuser first

$ python manage.py createsuperuser

Django URLs

URLs tell our app what to do when someone visits. Let's add some to mysite/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),

]

Now that we have our global site urls set up, we can add the urls for the blog

from django.urls import path
from . import views

urlpatterns = [
    path('', views.post_list, name='post_list'),
]

Django views – time to create!

let's add that post_list view to blog/views.py

from django.shortcuts import render
from django.utils import timezone
from blog.models import Post

# Create your views here.
def post_list(request):
    posts = Post.objects.filter(created_date__lte=timezone.now()).order_by('created_date')

    return render(request, 'blog/post_list.html', {
        'posts': posts
    })

Now we can test it out at localhost:8000/

Django Templates

Let's create a tempalte in blog/templates/blog/post_list.html


<html>
    <head>
        <title>Django Girls blog</title>
    </head>
	<div>
	    <h1><a href="/">Django Girls Blog</a></h1>
	</div>

	{% for post in posts %}
	    <div>
		<p>published: {{ post.created_date }}</p>
		<h2><a href="">{{ post.title }}</a></h2>
		<p>{{ post.text|linebreaksbr }}</p>
	    </div>
	{% endfor %}
    </body>
</html>

CSS – make it pretty!

To use the wonderful Bootstrap thing, add this to the head of the template

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">