django tutorial - Part 1. Install, Apps, Routes, Templates

Categories:   web development  
Tags:   python   django  

django is one of the most popular python web framework which uses the Model View Template design pattern. It’s packed with tons of features that allow developer’s to launch websites very quickly.

django websites are built the django way but it should still fit a wide range of use cases. For smaller projects or ones that require more flexibility, the Flask framework is also available for python developers. My Flask notes can be found here.

django is frequently compared to laravel which is a popular PHP web framework. For a glimpse of what laravel can do, check out my notes on laravel.


This is part 1 of my “django study Notes”.

We’ll cover more in the next post.

Credits:

I repost content I study, this helps me learn quicker.

This post covers parts 1 ~ 3 in Corey Schafer’s django tutorial.

Prerequisites

  • Python Basics: Learn everything up to classes
  • Solid HTML: Can you create a static 3 page website?
  • Basic CSS: What are the 3 ways to add css to your document? What’s a class?
  • Basic Javascript: Can you make an alert box pop up? Can you add a modal from bootstrap?
  • Hosting: Can you publish a simple website online?
  • Command line basics: (cd, ls, ls -al, cd foldername, cd ..)
  • What’s the differenct between a relative link and an absolute link?
  • A text editor: Visual Studio code is nice, it’s got an integrated terminal
  • git, github: You should start using git even if your not coding in a team.
  • linux server administration basics - for deploying our website.

Initial stuff

  • Install python, create a folder for your project
  • Use a virtual environment (I will use virtualenv)
  • Install django
  • Install gitbash
  • Set up git for your project

Note: I’m using windows (commands may differ on mac.)

Install Python

You can download the latest version of Python and install it on your machine.

When you install Python on your PC, make sure you:

  • Select the option to add python to your PATH.
  • Install PIP.

Once you have python, create a folder to put your project in. I usually have all projects in: C:/projects/projectname.

Create a virtual environment

Why use a virtual environment?

By creating and activating a virtual environment, all packages you install in there are segregated from the rest of your machine.

This way, you have full control of the packages you need for each project.

You can then easily replicate this environment on other machines whether it be for a co-worker or a production server.

Open up a terminal inside the project folder and run:

$ pip install virtualenv
$ virtualenv .venv
$ source .venv/scripts/activate
$ pip install django
$ pip freeze > requirements.txt
  1. We installed virtualenv using pip.
  2. We created a virtual environment inside a .venv folder.
  3. We activated the virtual environment (the activate paths are different on mac and linux.)
  4. We installed django in our virtual environment.
  5. A list of installed packages are saved in the requirements.txt file.

Setting this up again on a new machine:

If you have the requirements.txt file, you can re-create this virtual environment on a different machine.

You can also use github to get access to your latest files.

Set up git

Download gitbash and check you can launch the gitbash terminal.

You can use a text editor like Atom and use the gitbash terminal separately but I prefer to use the integrated terminal in Visual Studio Code.

Make sure that you first set up gitbash as your terminal in Visual Studio Code.

set up github

  • Create an account on github.com and create a new repository there.
  • They should have instructions on how to start a project. Open up the terminal in your project folder & run something like:
$ echo ".venv/" >> .gitignore
$ git init
$ git add .
$ git commit -m 'this is my first commit'
$ git remote add origin https://github.com/<yourgithubusername>/<yourreponame>.git
$ git push -u origin master
  1. We created a .gitignore file with .venv/. We don’t need git to track this. We can replicate this with requirements.txt.
  2. We will initialize git in this directory (make sure you run this in your projects folder.)
  3. We will add everything we want to be tracked by git. (Don’t forget the dot at the end.)
  4. We commit the changes to our local machines repository.
  5. We add a remote repository (the github repo you just created.)
  6. We push (commit) our changes to our github repo.

Your project should now be pushed to github.

Now everytime you want to save your local changes to github, you can:

$ git add .
$ git commit -m 'the commit message'
$ git push

Everytime you want to download the latest changes from github you:

$ git remote update
$ git pull

If you want to download this project on a new machine,

In your new machine’s new project folder run:

$ git clone https://github.com/<youraccountname>/<yourprojectname>.git .
$ virtualenv .venv
$ source .venv/scripts/activate
$ pip install -r requirements.txt

Don’t forget the dot at the end of the git clone command.

Note: Once your comfortable with git, find out which files shouldn’t be version controlled.

Projects can include sensitive files that contain database passwords and secret_keys.

Create a django application

Open up the terminal in your project folder & run:

$ django-admin startproject <project_name> .
  • Don’t forget the dot at the end unless you want your project installed in another folder.

Your site should now be accessible on your local machine.

In your project folder, run:

$ python manage.py runserver

Your site should visible in your browser at http://localhost:8000.

To regain control of the command line, type Ctrl+C to stop the server.

Creating our first Route

  • import path & include in the main urls.py
  • define paths in main urls.py:
from django.contrib import admin
from django.urls import path, include

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

Create an App (called blog)

We just created a django project, but it’s common in django to further create app’s for diffrent parts of the website.

$ python manage.py startapp blog
  • import path, views & urlpatterns in the app’s blog/url.py file:
from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='blog-home'),
    path('about/', views.about, name='blog-about'),
]

Templates and Variables

  • create the templates folder for the app:
  • blog > templates > blog > home.html.
  • create the base.html, home.html & about.html.

Add the apps Config path into the main settings.py

  1. add the apps config path inside the settings.py’s INSTALLED_APPS list.
  2. the app’s config class is in the app’s apps.py file. e.g:
class BlogConfig(AppConfig)
  • add this in the main settings.py like so (assuming app’s name is blog):
INSTALLED_APPS = [
    'blog.apps.BlogConfig',

Render the template

  • in app’s view.py, use render
  • blog/views.py:
from django.shortcuts import render
from django.http import HttpResponse

posts = [
    {
        'author': 'John',
        'title': 'Blog Post 1',
        'content': 'First Post content',
        'date_posted': 'August 27 2018'
    },
    {
        'author': 'Jane',
        'title': 'Blog Post 2',
        'content': 'Second Post content',
        'date_posted': 'August 28 2018'
    }
]

def home(request):
    context = {
        'posts': posts
    }
    return render(request, 'blog/home.html', context)

def about(request):
    return render(request, 'blog/about.html', {'title': 'About'})
  • We have some dummy post content saved as context. This is passed in with the render to the home.html template as posts.

blog/base.html

  • blog/templates/blog/base.html:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

    <link rel="stylesheet" type="text/css" href="{% static 'blog/main.css' %}">

    {% if title %}
        <title>Django Blog - {{ title }}</title>
    {% else %}
        <title>Django Blog</title>
    {% endif %}
</head>
<body class="container">
    <header class="site-header">
        <nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
            <div class="container">
                <a class="navbar-brand mr-4" href="{% url 'blog-home' %}">Django Blog</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarToggle">
                    <div class="navbar-nav mr-auto">
                        <a class="nav-item nav-link" href="{% url 'blog-home' %}">Home</a>
                        <a class="nav-item nav-link" href="{% url 'blog-about' %}">About</a>
                    </div>
                    <!-- Navbar Right Side -->
                    <div class="navbar-nav">
                        <a class="nav-item nav-link" href="#">Login</a>
                        <a class="nav-item nav-link" href="#">Register</a>
                    </div>
                </div>
            </div>
        </nav>
    </header>
    <main role="main" class="container">
        <div class="row">
            <div class="col-md-8">
            {% block content %}{% endblock %}
            </div>
            <div class="col-md-4">
            <div class="content-section">
                <h3>Our Sidebar</h3>
                <p class='text-muted'>You can put any information here you'd like.
                <ul class="list-group">
                    <li class="list-group-item list-group-item-light">Latest Posts</li>
                    <li class="list-group-item list-group-item-light">Announcements</li>
                    <li class="list-group-item list-group-item-light">Calendars</li>
                    <li class="list-group-item list-group-item-light">etc</li>
                </ul>
                </p>
            </div>
            </div>
        </div>
    </main>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
</body>
</html>
  • This base.html is the main html template that has the header, navbar & footer. The other html templates will extend from this file.

  • We can use logics like conditionals and loops thanks to the default django template engine. We can also use the jinja2 template engine if we want.

blog/home.html

  • blog/templates/blog/home.html:
{% extends "blog/base.html" %}

{% block content %}
    {% for post in posts %}
    <article class="media content-section">
        <div class="media-body">
            <div class="article-metadata">
                <a class="mr-2" href="#">{{ post.author }}</a>
                <small class="text-muted">{{ post.date_posted }}</small>
            </div>
            <h2><a class="article-title" href="#">{{ post.title }}</a></h2>
            <p class="article-content">{{ post.content }}</p>
        </div>
    </article>
    {% endfor %}
{% endblock content %}
  • We can extend from the base.html template which makes our code very organized.

  • Since we passed in the dummy posts variable in the app’s views.py file, this template can access them.

blog/about.html

  • blog/templates/blog/about.html:
{% extends "blog/base.html" %}

{% block content %}
    <h1>Blog About !</h1>
{% endblock content %}

Adding CSS

  • We need to add a static folder for the CSS.
  • The structure will be: blog > static > blog > main.css.
  • We already loaded this in the top of base.html:
{% load static %}
  • We also included the css file in the base.html file:
<link rel="stylesheet" type="text/css" href="{% static 'blog/main.css' %}">

The actual main.css file

  • blog/static/blog/main.css:
body {
    background: #fafafa;
    color: #333333;
    margin-top: 5rem;
  }

  h1, h2, h3, h4, h5, h6 {
    color: #444444;
  }

  ul {
    margin: 0;
  }

  .bg-steel {
    background-color: #5f788a;
  }

  .site-header .navbar-nav .nav-link {
    color: #cbd5db;
  }

  .site-header .navbar-nav .nav-link:hover {
    color: #ffffff;
  }

  .site-header .navbar-nav .nav-link.active {
    font-weight: 500;
  }

  .content-section {
    background: #ffffff;
    padding: 10px 20px;
    border: 1px solid #dddddd;
    border-radius: 3px;
    margin-bottom: 20px;
  }

  .article-title {
    color: #444444;
  }

  a.article-title:hover {
    color: #428bca;
    text-decoration: none;
  }

  .article-content {
    white-space: pre-line;
  }

  .article-img {
    height: 65px;
    width: 65px;
    margin-right: 16px;
  }

  .article-metadata {
    padding-bottom: 1px;
    margin-bottom: 4px;
    border-bottom: 1px solid #e3e3e3
  }

  .article-metadata a:hover {
    color: #333;
    text-decoration: none;
  }

  .article-svg {
    width: 25px;
    height: 25px;
    vertical-align: middle;
  }

  .account-img {
    height: 125px;
    width: 125px;
    margin-right: 20px;
    margin-bottom: 16px;
  }

  .account-heading {
    font-size: 2.5rem;
  }

use absolute paths in django with url patterns

  • We don’t use this:
<a class="nav-item nav-link" href="/">Home</a>
  • Instead we are using:
<a class="nav-item nav-link" href="{% url 'blog-home' %}">Home</a>
  • We are referencing the names for the links which we set it the app’s urls.py file.

  • Commands used thus far:

django-admin startproject <project_name>
python manage.py startapp <app_name>
python manage.py runserver

Summary

  • We create a django project with a blog app.
  • We set up the templates & static folders within the app.
  • We used template inheritance and django’s template engine.
  • We added bootstrap to the project.
  • We are passing in variables into the template.
  • We are using conditionals and loops in the template.

I think we will end this section here.

This post covers parts 1 ~ 3 in Corey Schafer’s django tutorial.

We’ll cover more in the next post.

Related Products



Categories:   web development  
Tags:   python   django  
Previous Article