Skip to content

personal repository for learning Django

License

Notifications You must be signed in to change notification settings

idflores/django-tutorial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Django Tutorial

My personal repository to learn Django from DjangoProject.com


Using virtualenv

(note: used as a "container" environment for the project)

Install

sudo pip install virtualenv

Start a new virtualenv "container"

virtualenv directory/name

To use Python3 instead:

virtualenv -p python3 directory/name

Usage

activate

source bin/activate

deactivate

deactivate

example

notice how, while activated, python and pip point to the packages defined inside the environment:

Install Django

With virtualenv activated, run the following command:

pip install Django

example

The Django Project Tutorial

Tutorial Reference: https://docs.djangoproject.com/en/1.11/intro/tutorial01/


Start a new Django project

django-admin startproject nameOfYourSite

Run the Development Django Web Server

python manage.py runserver

Models

Models and Database Migration

from: https://docs.djangoproject.com/en/1.11/intro/tutorial02/#activating-models

The 3-Step Guide to Model Changes

  • change your models (in models.py)
  • run python manage.py makemigrations to create migration for those changes
  • run python manage.py migrate to apply those changes to the databases

Django/Python3 Shell (important)

Rather than calling python in our virtualenv, we use

python manage.py shell

manage.py will set "the DJANGO_SETTINGS_MODULE environment variable, which gives Django the Python import path to your mysite/settings.py file."


Views

URLConf

"A URLConf maps URL patterns to views." See djnago.urls.

Responsibility

From: Django >> #write-views-that-actually-do-something

(Important) Each view must be responsible for at least 1 of 2 things:

  • returning an HttpResponse object
  • raising an HTTP 404 exception

The rest, you can determine...

  • read database records
  • use Django's template system or a 3rd party's
  • generate a PDF, XML, ZIP, etc.
  • execute Python libraries

The render() shortcut method

From: Django >> #a-shortcut-render

Motivation: It is very common to perform the following idiom:

from django.http import HttpResponse
from django.template import loader

def view_name(request):

    # (1) load the template
    template = loader.get_template('app_name/index.html')

    # (2) fill the context dictionary
    context = {
        'context_dictionary': context_object,
    }

    # (3) return the required HttpResponse
    return HttpResponse(template.render(context, request))

Shortcut: Django provides the following as a Shortcut

from django.shortcuts import render

def view_name(request):
  # (1) fill the context
  context = {'context_dictionary': context_object}

  # (2) render loads the response and satisfies the HttpResponse
  return render(request, 'app_name/index.html', context)

The get_object_or_404() shortcut method

From: Django >> #a-shortcut-get-object-or-404

Motivation: It is very common to perform the following idiom; in addition, not using the subsequent shortcut couples the view and model layers of Django architecture which is ill-advised:

from django.http import Http404
from django.shortcuts import render

def view_name(request):

  # (1) perform a get()
  try:
    var_name = Object.objects.get(<object_key>)

  # (2) if get() is undefined, raise an exception
  except Object.DoesNotExist:
    raise Http404("<Object> does not exist")

  # (3) render a response
  return render(request, 'app_name/view_name.html', {'var_name': var_name})

Shortcut: Django provides the following as a Shortcut

from django.shortcuts import get_object_or_404, render

def view_name(request):

  # (1) perform the try/except idiom
  var_name = get_object_or_404(<object>)

  # (2) render a response
  return render(request, 'app_name/view_name.html', {'var_name': var_name})

Generic Views

For some of the views defined in the tutorial, the author indicates that Django has generic views that can perform the same action.

Specifically, DetailView and ListView can be called by extending the django.views.generic module.

The following is an example of using these generic views with the conventional naming syntax:

# <app_name>/views.py

from django.views import generic

class IndexView(generic.ListView):
    template_name = '<app_name>/<model_name>_<template_name>.html'

    # overrides the automatically generated context
    context_object_name = '<context_object_name>'

    def get_queryset(self):
        """Return the last five published <Objects>."""
        return <Object>.objects.order_by('-pub_date')[:5]


class DetailView(generic.DetailView):
    model = <model_name>
    template_name = '<app_name>/<model_name>_<template_name>.html'

Templates

Note: Django will automatically search for a directory called `templates` in each application context.

Template Namespacing

Folder Structure

(Important) Django chooses application templates by order. To prevent confusion, it is convention to "namespace" your templates by "putting those templates inside another directory named for the application itself".

  • <application_name>
    • ...
    • templates
      • <appliaction_name> (this is namespacing)
        • ...
        • ...
    • ...

URLs

(Important) To prevent confusion in URLs, defining the app_name variable in urls.py of your Django application is convention:

In your urls.py file:

# <app_name>/urls.py

from django.conf.urls import url
from . import views

app_name = '<app_name>'

urlpatterns = [
  # ...
  url(<regexp>, views.<view_name>, name='<view_name>'),
  # ...
]

In your templates/<app_name>/<template_name>.html file:

<!-- <app_name>/templates/<app_name>/<template_name>.html -->

<a href="{% url '<app_name>:<view_name>' %}" />

Test Development

Notes

  • Django's testing system will automatically search for any file whose name begins with "test".
    • Examples: "tests.py", "test_ui.py"
  • Check code coverage to spot untested or dead code

Running the test

python manage.py test <app_name>

Testing Guidlines

  • use a separate TestCase for each model or view
  • use a separate test method for each set of conditions you want to test
  • use test method names that describe their function
  • If you can’t test a piece of code, that code should be refactored or removed

Testing Tools with Django


Front-End Development ("Static Files")

Notes

  • django.contrib.staticfiles >> collects static files from each application to a single location for production serving
    • similar to what WebPack does for NodeJS
  • Django automatically searches for static files from a directory named static
  • the directory static should follow the same namespacing convention discussed in Templates

Including a static file

.css Files

In your template file, add the following to the top:

{% load static %}

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

Caution: the {% static %} template tag in href generates the absoulte URL of the static .css file you are importing. Note, that since stylesheets are not generated by Django, relative paths must be used to link static files between each other.

  • it's possible to change STATIC_URL (used by {% static %}) to prevent modifying paths in your static files.

References


Customizing Djagno's Admin Form

General Practice

Anytime you change the admin options for a model:

  • create a model class
    • convention: class <model_name>Admin(admin.ModelAdmin):
  • pass it as a subsequent argument to admin.site.register()

Packaging Your App for Production

Prerequisites

Packaging Tool: setuptools (documentation)

Install

With virtualenv activated...

pip install setuptools

Package The Django application

  1. outside the project directory, make a new directory to hold the application
    • prepend your app with django- to designate the Python package as Django specific
  2. copy the Django app directory from the project directory to the new directory outside the project directory
  3. create a README.rst file
  4. create a LICENSE file
  5. create a setup.py file

Example content:

import os
from setuptools import find_packages, setup

with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
    README = readme.read()

# allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))

setup(
    name='django-polls',
    version='0.1',
    packages=find_packages(),
    include_package_data=True,
    license='BSD License',  # example license
    description='A simple Django app to conduct Web-based polls.',
    long_description=README,
    url='https://www.example.com/',
    author='Your Name',
    author_email='yourname@example.com',
    classifiers=[
        'Environment :: Web Environment',
        'Framework :: Django',
        'Framework :: Django :: X.Y',  # replace "X.Y" as appropriate
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',  # example license
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        # Replace these appropriately if you are stuck on Python 2.
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Topic :: Internet :: WWW/HTTP',
        'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
    ],
)
  1. make a docs directory
  2. create a MANIFEST.in file

Example content:

include LICENSE
include README.rst
recursive-include <app_name>/static *
recursive-include <app_name>/templates *
recursive-include docs *
  1. Your folder structure should resemble the following:

    • <parent_directory>/
      • bin/
      • django-<app_name>/ <-- this is your new application package
        • docs/
        • <app_name>/ <-- this is your copied application
        • LICENSE
        • MANIFEST.in
        • README.rst
        • setup.py
      • include/
      • lib/
      • <django_project_name>/
        • db.sqlite3
        • manage.py
        • <django_project_name>/
        • <app_name>/ <-- copy this!
  2. Build the package from with an activated virtualenv in the application directory

python setup.py sdist
  1. Distribute the generated .tar.gz file in the new /django-<app_name>/dist directory

Resources