Chapter 11 ■ the World Wide Web
207
• djbank/settings.py: This contains the plug-ins and configuration that govern how the
application loads and runs. The only change I made to the defaults written by Django 1.7 is
a last line that points Django at the static/ files directory sitting in the main chapter11/
directory so that the Django application can share the same style.css file that was used by
Listing 11-2 and Listing 11-8.
• djbank/templates/*.html: The page templates are a bit more primitive than the Jinja2
templates shown in Listings 11-3 through 11-6 because the Django template language is less
convenient and less powerful. But, because the basic syntax is the same, the differences are
not worth discussion in this book. Consult the documentation of both template systems if you
want to learn the details.
• djbank/wgsi.py: This offers a WSGI callable that a WSGI-compliant web server, whether
Gunicorn or Apache (see Chapter 10), can call to get the payments application up
and running.
The remaining four files are interesting for the way in which the framework, without needing any extensions,
already supports many common patterns of which Python code can take advantage.
Thanks to its built-in object-relational mapper (ORM), Django absolves the application of having to know how
to write any SQL queries of its own. The entire issue of proper quoting of SQL values disappears with it. Listing 11-9
describes the database table by listing its fields in a declarative Python class, which will be used to represent the
table rows when they are returned. Django lets you attach complicated validation logic to a class like this, if your data
restrictions go beyond those that can be expressed by the field types alone.
Listing 11-9. The models.py for the Django App
#!/usr/bin/env python3
Foundations of Python Network Programming, Third Edition
https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter11/djbank/models.py
Model definitions for our Django application.
from django.db import models
from django.forms import ModelForm
class Payment(models.Model):
debit = models.CharField(max_length=200)
credit = models.CharField(max_length=200, verbose_name='To account')
dollars = models.PositiveIntegerField()
memo = models.CharField(max_length=200)
class PaymentForm(ModelForm):
class Meta:
model = Payment
fields = ['credit', 'dollars', 'memo']
The bottom class declaration tells Django to prepare a form for creating and editing database rows. It will ask the
user only about the three fields listed, leaving the debit field for you to fill in from the currently logged-in username.
This class, as you will see, is able to face in both directions in the web app’s conversation with the user: it can render
the form as a series of HTML fields, and then it can turn around and parse the HTTP POST data that comes
back once the form is submitted in order to build or modify a Payment database row.
When you are using a micro-framework such as Flask, you will have to choose an outside library to support
operations like this. SQLAlchemy, for example, is a renowned ORM, and many programmers choose not to work with
Django specifically so that they can enjoy SQLAlchemy’s power and elegance.