Client Server Web Apps with JavaScript and Java Rich Scalable and RESTful 1st...zubinrlondoit
Client Server Web Apps with JavaScript and Java Rich Scalable and RESTful 1st Edition Saternos Casimir
Client Server Web Apps with JavaScript and Java Rich Scalable and RESTful 1st Edition Saternos Casimir
Client Server Web Apps with JavaScript and Java Rich Scalable and RESTful 1st Edition Saternos Casimir
Programming Google App Engine Build and Run Scalable Web Apps on Google s Inf...keftonoztas
Programming Google App Engine Build and Run Scalable Web Apps on Google s Infrastructure Animal Guide 1st Edition Dan Sanderson
Programming Google App Engine Build and Run Scalable Web Apps on Google s Infrastructure Animal Guide 1st Edition Dan Sanderson
Programming Google App Engine Build and Run Scalable Web Apps on Google s Infrastructure Animal Guide 1st Edition Dan Sanderson
Using Google App Engine 1st Edition Charles Severance 2024 scribd downloadsrengmanoans
Using Google App Engine 1st Edition Charles Severance ready for instant download post-payment at https://ebookfinal.com/download/using-google-app-engine-1st-edition-charles-severance. Browse more textbooks and ebooks in https://ebookfinal.com Download full PDF chapter.
Using Google App Engine 1st Edition Charles Severancerikamemurice
Using Google App Engine 1st Edition Charles Severance
Using Google App Engine 1st Edition Charles Severance
Using Google App Engine 1st Edition Charles Severance
Instant download Developing Backbone js Applications Addy Osmani pdf all chapterdinetvenitja
Download Developing Backbone js Applications Addy Osmani instantly post-payment at https://ebookultra.com/download/developing-backbone-js-applications-addy-osmani. More textbooks and ebooks available in https://ebookultra.com Get PDF of full chapter.
High Performance JavaScript Build Faster Web Application Interfaces 1st Editi...yarecofuxxa58
High Performance JavaScript Build Faster Web Application Interfaces 1st Edition Nicholas C. Zakas
High Performance JavaScript Build Faster Web Application Interfaces 1st Edition Nicholas C. Zakas
High Performance JavaScript Build Faster Web Application Interfaces 1st Edition Nicholas C. Zakas
Learning React Native Building Native Mobile Apps with JavaScript 2nd Edition...oquinberin6r
Learning React Native Building Native Mobile Apps with JavaScript 2nd Edition Bonnie Eisenman
Learning React Native Building Native Mobile Apps with JavaScript 2nd Edition Bonnie Eisenman
Learning React Native Building Native Mobile Apps with JavaScript 2nd Edition Bonnie Eisenman
[Ebooks PDF] download AngularJS 1st Edition Brad Green full chapterskiciunonge
Secure your copy of AngularJS 1st Edition Brad Green instantly after payment at https://ebookgate.com/product/angularjs-1st-edition-brad-green. Find more textbooks and ebooks in https://ebookgate.com Download complete chapter PDF.
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossierjoicyikoi
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthyzeemetapa
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthy
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthy
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthy
Learning the iPhone SDK for JavaScript Programmers Create Native Apps with Ob...matbarnargis59
Learning the iPhone SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Danny Goodman
Learning the iPhone SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Danny Goodman
Learning the iPhone SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Danny Goodman
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st ...assangkaoua
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st Edition Matt Neuburg
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st Edition Matt Neuburg
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st Edition Matt Neuburg
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Func...romergalbowx
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles 1st Edition Ben Weidig
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles 1st Edition Ben Weidig
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles 1st Edition Ben Weidig
Learning Swift Building Apps for OSX, iOS, and Beyond Jon Manningbatyegrocez1
Learning Swift Building Apps for OSX, iOS, and Beyond Jon Manning
Learning Swift Building Apps for OSX, iOS, and Beyond Jon Manning
Learning Swift Building Apps for OSX, iOS, and Beyond Jon Manning
- Django is a free open source web framework written in Python that allows for rapid development of secure and maintainable websites.
- It follows the MVT (Model View Template) architectural pattern with Models representing data, Views handling business logic, and Templates for presentation.
- To create a Django project, you install Django, start a project with django-admin, add apps, define models, views, URLs, templates, and test. Django provides generated starter code and admin interface.
- An example Todo app was demonstrated with a Task model having fields like name, description, owner, responsibilities, and completion status.
Mobile app development with Ionic cross platform apps with Ionic Angular and ...sestayobstk2
Mobile app development with Ionic cross platform apps with Ionic Angular and Cordova Griffith
Mobile app development with Ionic cross platform apps with Ionic Angular and Cordova Griffith
Mobile app development with Ionic cross platform apps with Ionic Angular and Cordova Griffith
This document introduces Django, an open-source Python web framework. It discusses what Django is, why it is useful for building dynamic web applications, and some of its key features like automatic admin interfaces and convention over configuration. The document then provides a tutorial on basic Django components like models, urls, views and templates. It concludes by listing additional Django resources and information about Usware Technologies, the company presenting.
Learning the iOS 4 SDK for JavaScript Programmers Create Native Apps with Obj...thoramenzab0
Learning the iOS 4 SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Goodman
Learning the iOS 4 SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Goodman
Learning the iOS 4 SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Goodman
Learning Swift 3 Early release 3rd Edition Jonathan Manningnieysaiotti
Learning Swift 3 Early release 3rd Edition Jonathan Manning
Learning Swift 3 Early release 3rd Edition Jonathan Manning
Learning Swift 3 Early release 3rd Edition Jonathan Manning
Angular Up and Running Learning Angular Step by Step 1st Edition Shyam Seshadrimaneskortyjt
Angular Up and Running Learning Angular Step by Step 1st Edition Shyam Seshadri
Angular Up and Running Learning Angular Step by Step 1st Edition Shyam Seshadri
Angular Up and Running Learning Angular Step by Step 1st Edition Shyam Seshadri
Using Docker Developing and Deploying Software with Containers 1st Edition Ad...abucdaroga
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Final gatsby + wagtail - Inclusive product weekDawn Wages
This document discusses using Gatsby and Wagtail together for content management and progressive web app generation. It describes how to set up a Gatsby site connected to a Wagtail backend with GraphQL, allowing content to be managed in Wagtail and rendered in Gatsby. Key steps include installing and configuring the necessary packages, creating a blog app in Wagtail, setting up GraphQL endpoints, and connecting the Gatsby site to the Wagtail GraphQL API.
Using Docker Developing and Deploying Software with Containers 1st Edition Ad...eljantnezar
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET...barbuhalahdl
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET MVC 1st Edition Jess Chadwick
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET MVC 1st Edition Jess Chadwick
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET MVC 1st Edition Jess Chadwick
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...larencebapu132
This is short and accurate description of World war-1 (1914-18)
It can give you the perfect factual conceptual clarity on the great war
Regards Simanchala Sarab
Student of BABed(ITEP, Secondary stage)in History at Guru Nanak Dev University Amritsar Punjab 🙏🙏
Title: A Quick and Illustrated Guide to APA Style Referencing (7th Edition)
This visual and beginner-friendly guide simplifies the APA referencing style (7th edition) for academic writing. Designed especially for commerce students and research beginners, it includes:
✅ Real examples from original research papers
✅ Color-coded diagrams for clarity
✅ Key rules for in-text citation and reference list formatting
✅ Free citation tools like Mendeley & Zotero explained
Whether you're writing a college assignment, dissertation, or academic article, this guide will help you cite your sources correctly, confidently, and consistent.
Created by: Prof. Ishika Ghosh,
Faculty.
📩 For queries or feedback: [email protected]
Ad
More Related Content
Similar to Lightweight Django 1st Edition Julia Elman (20)
[Ebooks PDF] download AngularJS 1st Edition Brad Green full chapterskiciunonge
Secure your copy of AngularJS 1st Edition Brad Green instantly after payment at https://ebookgate.com/product/angularjs-1st-edition-brad-green. Find more textbooks and ebooks in https://ebookgate.com Download complete chapter PDF.
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossierjoicyikoi
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
Developing Android Applications with Adobe AIR 1st Edition Véronique Brossier
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthyzeemetapa
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthy
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthy
Exam Ref 70 486 Developing ASP NET MVC 4 Web Applications William Penberthy
Learning the iPhone SDK for JavaScript Programmers Create Native Apps with Ob...matbarnargis59
Learning the iPhone SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Danny Goodman
Learning the iPhone SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Danny Goodman
Learning the iPhone SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Danny Goodman
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st ...assangkaoua
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st Edition Matt Neuburg
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st Edition Matt Neuburg
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st Edition Matt Neuburg
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Func...romergalbowx
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles 1st Edition Ben Weidig
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles 1st Edition Ben Weidig
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Functional Principles 1st Edition Ben Weidig
Learning Swift Building Apps for OSX, iOS, and Beyond Jon Manningbatyegrocez1
Learning Swift Building Apps for OSX, iOS, and Beyond Jon Manning
Learning Swift Building Apps for OSX, iOS, and Beyond Jon Manning
Learning Swift Building Apps for OSX, iOS, and Beyond Jon Manning
- Django is a free open source web framework written in Python that allows for rapid development of secure and maintainable websites.
- It follows the MVT (Model View Template) architectural pattern with Models representing data, Views handling business logic, and Templates for presentation.
- To create a Django project, you install Django, start a project with django-admin, add apps, define models, views, URLs, templates, and test. Django provides generated starter code and admin interface.
- An example Todo app was demonstrated with a Task model having fields like name, description, owner, responsibilities, and completion status.
Mobile app development with Ionic cross platform apps with Ionic Angular and ...sestayobstk2
Mobile app development with Ionic cross platform apps with Ionic Angular and Cordova Griffith
Mobile app development with Ionic cross platform apps with Ionic Angular and Cordova Griffith
Mobile app development with Ionic cross platform apps with Ionic Angular and Cordova Griffith
This document introduces Django, an open-source Python web framework. It discusses what Django is, why it is useful for building dynamic web applications, and some of its key features like automatic admin interfaces and convention over configuration. The document then provides a tutorial on basic Django components like models, urls, views and templates. It concludes by listing additional Django resources and information about Usware Technologies, the company presenting.
Learning the iOS 4 SDK for JavaScript Programmers Create Native Apps with Obj...thoramenzab0
Learning the iOS 4 SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Goodman
Learning the iOS 4 SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Goodman
Learning the iOS 4 SDK for JavaScript Programmers Create Native Apps with Objective C and Xcode 1st Edition Goodman
Learning Swift 3 Early release 3rd Edition Jonathan Manningnieysaiotti
Learning Swift 3 Early release 3rd Edition Jonathan Manning
Learning Swift 3 Early release 3rd Edition Jonathan Manning
Learning Swift 3 Early release 3rd Edition Jonathan Manning
Angular Up and Running Learning Angular Step by Step 1st Edition Shyam Seshadrimaneskortyjt
Angular Up and Running Learning Angular Step by Step 1st Edition Shyam Seshadri
Angular Up and Running Learning Angular Step by Step 1st Edition Shyam Seshadri
Angular Up and Running Learning Angular Step by Step 1st Edition Shyam Seshadri
Using Docker Developing and Deploying Software with Containers 1st Edition Ad...abucdaroga
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Final gatsby + wagtail - Inclusive product weekDawn Wages
This document discusses using Gatsby and Wagtail together for content management and progressive web app generation. It describes how to set up a Gatsby site connected to a Wagtail backend with GraphQL, allowing content to be managed in Wagtail and rendered in Gatsby. Key steps include installing and configuring the necessary packages, creating a blog app in Wagtail, setting up GraphQL endpoints, and connecting the Gatsby site to the Wagtail GraphQL API.
Using Docker Developing and Deploying Software with Containers 1st Edition Ad...eljantnezar
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Using Docker Developing and Deploying Software with Containers 1st Edition Adrian Mouat
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET...barbuhalahdl
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET MVC 1st Edition Jess Chadwick
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET MVC 1st Edition Jess Chadwick
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET MVC 1st Edition Jess Chadwick
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...larencebapu132
This is short and accurate description of World war-1 (1914-18)
It can give you the perfect factual conceptual clarity on the great war
Regards Simanchala Sarab
Student of BABed(ITEP, Secondary stage)in History at Guru Nanak Dev University Amritsar Punjab 🙏🙏
Title: A Quick and Illustrated Guide to APA Style Referencing (7th Edition)
This visual and beginner-friendly guide simplifies the APA referencing style (7th edition) for academic writing. Designed especially for commerce students and research beginners, it includes:
✅ Real examples from original research papers
✅ Color-coded diagrams for clarity
✅ Key rules for in-text citation and reference list formatting
✅ Free citation tools like Mendeley & Zotero explained
Whether you're writing a college assignment, dissertation, or academic article, this guide will help you cite your sources correctly, confidently, and consistent.
Created by: Prof. Ishika Ghosh,
Faculty.
📩 For queries or feedback: [email protected]
How to track Cost and Revenue using Analytic Accounts in odoo Accounting, App...Celine George
Analytic accounts are used to track and manage financial transactions related to specific projects, departments, or business units. They provide detailed insights into costs and revenues at a granular level, independent of the main accounting system. This helps to better understand profitability, performance, and resource allocation, making it easier to make informed financial decisions and strategic planning.
How to Customize Your Financial Reports & Tax Reports With Odoo 17 AccountingCeline George
The Accounting module in Odoo 17 is a complete tool designed to manage all financial aspects of a business. Odoo offers a comprehensive set of tools for generating financial and tax reports, which are crucial for managing a company's finances and ensuring compliance with tax regulations.
The ever evoilving world of science /7th class science curiosity /samyans aca...Sandeep Swamy
The Ever-Evolving World of
Science
Welcome to Grade 7 Science4not just a textbook with facts, but an invitation to
question, experiment, and explore the beautiful world we live in. From tiny cells
inside a leaf to the movement of celestial bodies, from household materials to
underground water flows, this journey will challenge your thinking and expand
your knowledge.
Notice something special about this book? The page numbers follow the playful
flight of a butterfly and a soaring paper plane! Just as these objects take flight,
learning soars when curiosity leads the way. Simple observations, like paper
planes, have inspired scientific explorations throughout history.
Exploring Substances:
Acidic, Basic, and
Neutral
Welcome to the fascinating world of acids and bases! Join siblings Ashwin and
Keerthi as they explore the colorful world of substances at their school's
National Science Day fair. Their adventure begins with a mysterious white paper
that reveals hidden messages when sprayed with a special liquid.
In this presentation, we'll discover how different substances can be classified as
acidic, basic, or neutral. We'll explore natural indicators like litmus, red rose
extract, and turmeric that help us identify these substances through color
changes. We'll also learn about neutralization reactions and their applications in
our daily lives.
by sandeep swamy
INTRO TO STATISTICS
INTRO TO SPSS INTERFACE
CLEANING MULTIPLE CHOICE RESPONSE DATA WITH EXCEL
ANALYZING MULTIPLE CHOICE RESPONSE DATA
INTERPRETATION
Q & A SESSION
PRACTICAL HANDS-ON ACTIVITY
Understanding P–N Junction Semiconductors: A Beginner’s GuideGS Virdi
Dive into the fundamentals of P–N junctions, the heart of every diode and semiconductor device. In this concise presentation, Dr. G.S. Virdi (Former Chief Scientist, CSIR-CEERI Pilani) covers:
What Is a P–N Junction? Learn how P-type and N-type materials join to create a diode.
Depletion Region & Biasing: See how forward and reverse bias shape the voltage–current behavior.
V–I Characteristics: Understand the curve that defines diode operation.
Real-World Uses: Discover common applications in rectifiers, signal clipping, and more.
Ideal for electronics students, hobbyists, and engineers seeking a clear, practical introduction to P–N junction semiconductors.
This chapter provides an in-depth overview of the viscosity of macromolecules, an essential concept in biophysics and medical sciences, especially in understanding fluid behavior like blood flow in the human body.
Key concepts covered include:
✅ Definition and Types of Viscosity: Dynamic vs. Kinematic viscosity, cohesion, and adhesion.
⚙️ Methods of Measuring Viscosity:
Rotary Viscometer
Vibrational Viscometer
Falling Object Method
Capillary Viscometer
🌡️ Factors Affecting Viscosity: Temperature, composition, flow rate.
🩺 Clinical Relevance: Impact of blood viscosity in cardiovascular health.
🌊 Fluid Dynamics: Laminar vs. turbulent flow, Reynolds number.
🔬 Extension Techniques:
Chromatography (adsorption, partition, TLC, etc.)
Electrophoresis (protein/DNA separation)
Sedimentation and Centrifugation methods.
Geography Sem II Unit 1C Correlation of Geography with other school subjectsProfDrShaikhImran
The correlation of school subjects refers to the interconnectedness and mutual reinforcement between different academic disciplines. This concept highlights how knowledge and skills in one subject can support, enhance, or overlap with learning in another. Recognizing these correlations helps in creating a more holistic and meaningful educational experience.
Social Problem-Unemployment .pptx notes for Physiotherapy StudentsDrNidhiAgarwal
Unemployment is a major social problem, by which not only rural population have suffered but also urban population are suffered while they are literate having good qualification.The evil consequences like poverty, frustration, revolution
result in crimes and social disorganization. Therefore, it is
necessary that all efforts be made to have maximum.
employment facilities. The Government of India has already
announced that the question of payment of unemployment
allowance cannot be considered in India
CBSE - Grade 8 - Science - Chemistry - Metals and Non Metals - WorksheetSritoma Majumder
Introduction
All the materials around us are made up of elements. These elements can be broadly divided into two major groups:
Metals
Non-Metals
Each group has its own unique physical and chemical properties. Let's understand them one by one.
Physical Properties
1. Appearance
Metals: Shiny (lustrous). Example: gold, silver, copper.
Non-metals: Dull appearance (except iodine, which is shiny).
2. Hardness
Metals: Generally hard. Example: iron.
Non-metals: Usually soft (except diamond, a form of carbon, which is very hard).
3. State
Metals: Mostly solids at room temperature (except mercury, which is a liquid).
Non-metals: Can be solids, liquids, or gases. Example: oxygen (gas), bromine (liquid), sulphur (solid).
4. Malleability
Metals: Can be hammered into thin sheets (malleable).
Non-metals: Not malleable. They break when hammered (brittle).
5. Ductility
Metals: Can be drawn into wires (ductile).
Non-metals: Not ductile.
6. Conductivity
Metals: Good conductors of heat and electricity.
Non-metals: Poor conductors (except graphite, which is a good conductor).
7. Sonorous Nature
Metals: Produce a ringing sound when struck.
Non-metals: Do not produce sound.
Chemical Properties
1. Reaction with Oxygen
Metals react with oxygen to form metal oxides.
These metal oxides are usually basic.
Non-metals react with oxygen to form non-metallic oxides.
These oxides are usually acidic.
2. Reaction with Water
Metals:
Some react vigorously (e.g., sodium).
Some react slowly (e.g., iron).
Some do not react at all (e.g., gold, silver).
Non-metals: Generally do not react with water.
3. Reaction with Acids
Metals react with acids to produce salt and hydrogen gas.
Non-metals: Do not react with acids.
4. Reaction with Bases
Some non-metals react with bases to form salts, but this is rare.
Metals generally do not react with bases directly (except amphoteric metals like aluminum and zinc).
Displacement Reaction
More reactive metals can displace less reactive metals from their salt solutions.
Uses of Metals
Iron: Making machines, tools, and buildings.
Aluminum: Used in aircraft, utensils.
Copper: Electrical wires.
Gold and Silver: Jewelry.
Zinc: Coating iron to prevent rusting (galvanization).
Uses of Non-Metals
Oxygen: Breathing.
Nitrogen: Fertilizers.
Chlorine: Water purification.
Carbon: Fuel (coal), steel-making (coke).
Iodine: Medicines.
Alloys
An alloy is a mixture of metals or a metal with a non-metal.
Alloys have improved properties like strength, resistance to rusting.
1. Lightweight Django 1st Edition Julia Elman pdf
download
https://ebookgate.com/product/lightweight-django-1st-edition-
julia-elman/
Get Instant Ebook Downloads – Browse at https://ebookgate.com
2. Instant digital products (PDF, ePub, MOBI) available
Download now and explore formats that suit you...
Mastering Django Core 1st Edition Nigel George
https://ebookgate.com/product/mastering-django-core-1st-edition-nigel-
george/
ebookgate.com
Pro Django 2nd Edition Marty Alchin
https://ebookgate.com/product/pro-django-2nd-edition-marty-alchin/
ebookgate.com
Web Development with Django Cookbook Bendoraitis
https://ebookgate.com/product/web-development-with-django-cookbook-
bendoraitis/
ebookgate.com
Beginning Django E Commerce 1st Edition Jim Mcgaw (Auth.)
https://ebookgate.com/product/beginning-django-e-commerce-1st-edition-
jim-mcgaw-auth/
ebookgate.com
3. The Lightweight Treated Soil Method 1st Edition Takashi
Tsuchida
https://ebookgate.com/product/the-lightweight-treated-soil-method-1st-
edition-takashi-tsuchida/
ebookgate.com
Superworm Julia Donaldson
https://ebookgate.com/product/superworm-julia-donaldson/
ebookgate.com
Flexible Manufacture of Lightweight Frame Structures
Proceedings Kleiner
https://ebookgate.com/product/flexible-manufacture-of-lightweight-
frame-structures-proceedings-kleiner/
ebookgate.com
Radiology Strategies 1st Edition Julia Fielding
https://ebookgate.com/product/radiology-strategies-1st-edition-julia-
fielding/
ebookgate.com
Nature Anatomy Julia Rothman
https://ebookgate.com/product/nature-anatomy-julia-rothman/
ebookgate.com
5. Julia Elman & Mark Lavin
Lightweight
Django
USING REST, WEBSOCKETS & BACKBONE
6. PYTHON/WEB DEVELOPMENT
Lightweight Django
ISBN: 978-1-491-94594-0
US $39.99 CAN $41.99
“A great resource for
going beyond traditional
apps and learning how
Django can power the
backend of single-page
web applications.”
—Aymeric Augustin
Django core developer, CTO, oscaro.com
“Such a good idea—I think
this will lower the barrier
of entry for developers
even more… the more
I read, the more excited
I am!” —Barbara Shaurette
Python Developer, Cox Media Group
Twitter: @oreillymedia
facebook.com/oreilly
Howcanyoutakeadvantageof theDjangoframework tointegratecomplex
client-side interactions and real-time features into your web applications?
Through a series of rapid application development projects, this hands-on
book shows experienced Django developers how to include REST APIs,
WebSockets, and client-side MVC frameworks such as Backbone.js into
new or existing projects.
Learn how to make the most of Django’s decoupled design by choosing
the components you need to build the lightweight applications you want.
Once you finish this book, you’ll know how to build single-page applications
that respond to interactions in real time. If you’re familiar with Python and
JavaScript, you’re good to go.
■
■ Learn a lightweight approach for starting a new Django project
■
■ Break reusable applications into smaller services that
communicate with one another
■
■ Create a static, rapid prototyping site as a scaffold for websites
and applications
■
■ Build a REST API with django-rest-framework
■
■ Learn how to use Django with the Backbone.js MVC framework
■
■ Create a single-page web application on top of your REST API
■
■ Integrate real-time features with WebSockets and the Tornado
networking library
■
■ Use the book’s code-driven examples in your own projects
Julia Elman, a frontend developer and tech education advocate, started learning
Django in 2008 while working at World Online. She is one of the co-founders for
Girl Develop It RDU and PyLadies RDU, organizations that have helped over 850
women learn to program.
Mark Lavin is Technical Director at Caktus Consulting Group in Durham, North
Carolina. He came to Python web development after years of pricing derivatives
on Wall Street. Mark maintains several open source projects related to Django
development.
Lightweight
Django
Elman
&
Lavin
Julia Elman & Mark Lavin
Lightweight
Django
USING REST, WEBSOCKETS & BACKBONE
10. 3. Building a Static Site Generator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Creating Static Sites with Django 31
What Is Rapid Prototyping? 32
Initial Project Layout 32
File/Folder Scaffolding 32
Basic Settings 33
Page Rendering 35
Creating Our Base Templates 35
Static Page Generator 36
Basic Styling 39
Prototype Layouts and Navigation 41
Generating Static Content 46
Settings Configuration 46
Custom Management Command 47
Building a Single Page 49
Serving and Compressing Static Files 50
Hashing Our CSS and JavaScript Files 50
Compressing Our Static Files 51
Generating Dynamic Content 54
Updating Our Templates 54
Adding Metadata 56
4. Building a REST API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Django and REST 61
Scrum Board Data Map 62
Initial Project Layout 63
Project Settings 64
No Django Admin? 66
Models 66
Designing the API 69
Sprint Endpoints 69
Task and User Endpoints 71
Connecting to the Router 74
Linking Resources 74
Testing Out the API 77
Using the Browsable API 77
Adding Filtering 81
Adding Validations 86
Using a Python Client 89
Next Steps 91
iv | Table of Contents
11. 5. Client-Side Django with Backbone.js. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Brief Overview of Backbone 94
Setting Up Your Project Files 95
JavaScript Dependencies 96
Organization of Your Backbone Application Files 98
Connecting Backbone to Django 100
Client-Side Backbone Routing 102
Creating a Basic Home Page View 102
Setting Up a Minimal Router 103
Using _.template from Underscore.js 104
Building User Authentication 107
Creating a Session Model 107
Creating a Login View 111
Generic Form View 117
Authenticating Routes 120
Creating a Header View 121
6. Single-Page Web Application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
What Are Single-Page Web Applications? 131
Discovering the API 132
Fetching the API 132
Model Customizations 133
Collection Customizations 134
Building Our Home Page 135
Displaying the Current Sprints 135
Creating New Sprints 138
Sprint Detail Page 141
Rendering the Sprint 141
Routing the Sprint Detail 143
Using the Client State 144
Rendering the Tasks 146
AddTaskView 153
CRUD Tasks 156
Rendering Tasks Within a Sprint 156
Updating Tasks 160
Inline Edit Features 163
7. Real-Time Django. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
HTML5 Real-Time APIs 167
Websockets 168
Server-Sent Events 168
WebRTC 169
Table of Contents | v
12. Websockets with Tornado 169
Introduction to Tornado 170
Message Subscriptions 175
Client Communication 178
Minimal Example 179
Socket Wrapper 182
Client Connection 185
Sending Events from the Client 187
Handling Events from the Client 193
Updating Task State 195
8. Communication Between Django and Tornado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Receiving Updates in Tornado 199
Sending Updates from Django 201
Handling Updates on the Client 203
Server Improvements 204
Robust Subscriptions 204
Websocket Authentication 208
Better Updates 212
Secure Updates 214
Final Websocket Server 217
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
vi | Table of Contents
13. Preface
Since the creation of Django, a plethora of web frameworks have been created in various
open source communities. Frontend-focused web frameworks such as Angular.js, Em‐
ber.js, and Backbone.js have come out of the JavaScript community and become fore‐
runners in modern web development. Where does Django fit into all of this? How can
we integrate these client-side MVC frameworks into our current Django infrastructure?
Lightweight Django teaches you how to take advantage of Django’s Pythonic “batteries
included” philosophy. Its aim is to guide you through misconceptions that Django is
too “heavy” for rapid application development. From creating the world’s smallest
DjangoapplicationtobuildingaRESTfulAPI,LightweightDjangowillwalkyouthrough
how to take advantage of this popular Python web framework.
Why This Book?
We wanted to write this book primarily because we love Django. The community is
amazing, and there are so many resources to learn about Django and to develop appli‐
cations using it. However, we also felt like many of these resources, including the official
Django documentation, put too much emphasis on the power of Django and not on its
decoupled design. Django is a well-written framework, with numerous utilities for
building web applications included. What we want this book to highlight is how you
can break apart and potentially replace these components to pick and choose what best
suits the application you want to build. Similarly, we wanted to break down the typical
structure of Django projects and applications. Our goal is to get you to stop asking “how
do I do X in Django?” and instead ask “does Django provide anything to help me do X,
and if not, is something available in the community?”
In addition, we wanted to answer questions about where Django fits in a Web in which
more applications are built with heavy client-side interactions and real-time compo‐
nents, and paired with native mobile applications. As a framework, Django is agnostic
about the client, which leaves some users feeling like Django doesn’t have an answer for
vii
14. building these types of applications. We hope that this book can help shape how the
community approaches these types of problems. We want to see Django and its com‐
munity continue to grow, and we want to be a part of it for many more years to come.
Who Should Read This Book?
If you are interested in reading this book, you are most likely an intermediate Django
user. You’ve gone through the Django polls tutorial, as well as written a few basic
Django web applications, and are now wondering what the next steps are. Lightweight
Django serves as that next step to help outline how to utilize Django’s utilities and
simplicity.
Or you might be currently working on a Django project and wondering how to integrate
something like Backbone.js into your project. Lightweight Django will teach you some
best practices for integration and will give you a jumping-off point for building content-
rich web applications.
Who Should Not Read This Book?
While we feel that Lightweight Django is beneficial to developers from many back‐
grounds, there might be certain people who won’t find this book interesting. For those
of you who do not find writing Python and/or JavaScript pleasurable, this book is most
likely not for you. All of the concepts and examples revolve around these languages,
and they will be heavily used throughout each chapter. We also don’t recommend this
book for those who are brand new to Django.
About the Examples
Each of the example projects has been carefully crafted under the theme of rapid ap‐
plication development. In each chapter, you’ll learn how to build projects that assist
withprojectmanagement,tools,andteamcollaboration.Wewantedourreaderstobuild
projects that they find useful and can customize for their own use. In general, if example
code is offered with this book, you may use it in your programs and documentation.
You do not need to contact us for permission unless you’re reproducing a significant
portion of the code. For example, writing a program that uses several chunks of code
from this book does not require permission. Selling or distributing a CD-ROM of ex‐
amples from O’Reilly books does require permission. Answering a question by citing
this book and quoting example code does not require permission. Incorporating a sig‐
nificant amount of example code from this book into your product’s documentation
does require permission.
The code samples for this title can be found here: https://github.com/lightweightdjango/
examples.
viii | Preface
15. We appreciate, but do not require, attribution. An attribution usually includes the title,
author,publisher,andISBN.Forexample:“LightweightDjangobyJuliaElmanandMark
Lavin (O’Reilly). Copyright 2015 Julia Elman and Mark Lavin, 978-1-491-94594-0.”
If you feel your use of code examples falls outside fair use or the permission given above,
feel free to contact us at [email protected].
Organization of This Book
Chapter 1, The World’s Smallest Django Project
Creating lightweight and simple web applications is the core concept in this book.
In this chapter, you’ll be building a runnable, single-file “Hello World” Django
application.
Chapter 2, Stateless Web Application
Ever wonder how placeholder image services are created? Chapter 2 walks you
through how to build a stateless web application to generate placeholder image
URLs.
Chapter 3, Building a Static Site Generator
Rapid prototyping is a useful technique for creating and scaffolding web applica‐
tions. We’ll review the purposes of this technique by creating a static site generator
to help scaffold your team’s project.
Chapter 4, Building a REST API
RESTAPIsareanimportantpartofcreatingwebapplicationswithrichandrelevant
content. This is the chapter in which we start building out a large-scale Scrum board
application by using the django-rest-framework.
Chapter 5, Client-Side Django with Backbone.js
Chapter 5 continues with what we built in Chapter 4 by walking you through cre‐
ating a Backbone.js application that works with our newly made RESTful API. We’ll
touch on each component that creates a new Backbone application and how to sync
up this client-side framework with Django.
Chapter 6, Single-Page Web Application
Single-page web applications are a way in which we can create enriching client-side
web applications. In this chapter we’ll return to our simple Backbone application
and continue our progress by making it a robust single-page application.
Chapter 7, Real-Time Django
Creating web applications that respond to interactions in real time provides instant
gratification for our users. To complete our project from the previous two chapters,
we’lladdareal-timecomponenttoourScrumboardusingwebsocketsandTornado,
an asynchronous networking library written in Python.
Preface | ix
16. Chapter 8, Communication Between Django and Tornado
ConnectingthepowerofDjangototherobustbehaviorsofTornadoisanimportant
measure in creating scalable, real-time Django applications. In this chapter, we’ll
expand on our usage of the Tornado server by integrating the ability to work with
Django to create a secure and interactive relationship.
Conventions Used in This Book
The following typographical conventions are used in this book:
Italic
Indicates new terms, URLs, email addresses, filenames, and file extensions.
Constant width
Used for program listings, as well as within paragraphs to refer to program elements
such as variable or function names, databases, data types, environment variables,
statements, and keywords.
Constant width bold
Shows commands or other text that should be typed literally by the user.
Constant width italic
Shows text that should be replaced with user-supplied values or by values deter‐
mined by context.
Throughout the code examples, we will use an ellipsis (…) to denote that some of the
previously displayed content has been skipped to shorten long code examples or to skip
to the most relevant section of the code.
This element signifies a tip or suggestion.
This element signifies a general note.
This element indicates a warning or caution.
x | Preface
17. How to Contact Us
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
800-998-9938 (in the United States or Canada)
707-829-0515 (international or local)
707-829-0104 (fax)
We have a web page for this book, where we list errata, examples, and any additional
information. You can access this page at http://www.oreilly.com/catalog/
0636920032502.
To comment or ask technical questions about this book, send email to
[email protected].
For more information about our books, courses, conferences, and news, see our website
at http://www.oreilly.com.
Find us on Facebook: http://facebook.com/oreilly
Follow us on Twitter: http://twitter.com/oreillymedia
Watch us on YouTube: http://www.youtube.com/oreillymedia
Acknowledgments
Therearenumerouspeopletothankandwithoutwhomthisbookwouldnotbepossible.
We received amazing support from our editor, Meghan Blanchette.
Thank you to our technical reviewers—Aymeric Augustin, Jon Banafato, Barbara
Shaurette, and Marie Selvanadin— for your comments, both positive and negative,
which helped to shape and focus the book. Also thank you to Heather Scherer for shep‐
herding the technical review.
We are grateful to all the open source developers and contributors whose endless hours
of work were needed to make these tools available for us to use and write about.
Thank you to our early release readers for taking a chance on our unfinished work,
dealing with typos and poor formatting, and giving feedback and correcting mistakes.
Julia
Iwouldliketothankmywonderfulfamilyandclosefriendsfortheirsupportthroughout
the course of writing this book. To my husband, Andrew, for believing in my abilities,
Preface | xi
18. and for his constant encouragement and steadfast support during this long and bumpy
journey. To my daughter, Hannah, who is my inspiration and from whom I can always
grow my strength every step of the way. To my mother, Katherine, for pushing me
beyond what I ever thought I was capable of doing. To my stepfather, Tom, for teaching
me how to use a cordless drill, changing the oil in my car, and instilling in me the value
of hard work. Thank you to my brother, Alex, and sister, Elizabeth, for always cheering
me on from the sidelines. Thank you to my best friend, Jenny, for her constant love and
lifelong friendship.
Also, thank you to my wonderful coauthor, Mark, for his brilliance and friendship; he
is one of the most talented developers I have ever collaborated with. We made it to this
finish line together, and I cannot imagine going through this book writing journey with
anyone else.
I’d also like to thank the Python community and a few specific members who have
inspired, encouraged, and/or mentored me throughout my career: James Bennett, Sean
Bleier, Nathan Borror, Colin Copeland, Matt Croydon, Katie Cunningham, Selena
Deckelmann, Jacob Kaplan-Moss, Jessica McKellar, Jesse Noller, Christian Metts, Lynn
Root, Caleb Smith, Paul Smith, Karen Tracey, Malcolm Tredinnick, Ben Turner, and
Simon Willison.
Mark
First and foremost, this book would not be possible without the love and support of my
family. My wife, Beth, and daughter, Kennedy, put up with long hours and a grumpier
and more stressed version of me than they deserve. Also thanks to my brother, Matt,
for his insight and early feedback. Thank you to my parents and my brother James for
their lifetime of support.
Thank you to my coauthor, Julia. Our collaboration is a celebration of our friendship
and mutual respect. I will forever cherish our ability to work together to create some‐
thing greater than the sum of our contributions.
Finally, thank you to my coworkers at Caktus Group for your support in time, feedback,
and encouragement.
xii | Preface
19. Prerequisites
Before we dive in, this chapter is an outline of the knowledge and software requirements
you’ll need to follow the examples in this book.
Python
This book is aimed at developers with at least some previous Python experience, and in
this book we are using Python 3. In particular, the examples have been tested to run on
Python 3.3 and 3.4. Those familiar enough with Python may be able to work through
this book using Python 2.7, converting the example code as needed, though it is not
recommended. To read more about what is new in these versions of Python and to find
installation instructions for your system, visit https://www.python.org/downloads/.
We expect that you have Python installed on your local development machine, know
how to edit Python files, and know how to run them. Throughout this book, when we
reference Python on the command line, we will use python, though some systems or
installations may require using python3 or the full version, such as python3.3 or
python3.4. Similarly, when installing new packages, the examples will use pip, though
some installations may require using pip3. For this book, and Python development in
general, it is recommended that you create an isolated Python environment for each
project using virtualenv. Without an isolated environment, installing new Python
packages with pip may require root access or administrative rights on your computer.
We’ll assume that if this is the case, you will prefix the pip command with sudo or any
other commands you may need to gain such rights, but those prefixes will not be shown
in the examples.
xiii
20. Python Packages
The only Python package that is required before you start this book is Django. All of
the examples have been tested and written to work with Django 1.7. It is recommended
that you install with pip:
hostname $ pip install Django==1.7
As of August 2014, Django 1.7 was still in a release candidate phase.
If the preceding installation does not work, you can install the 1.7 pre-
release from the development branch with pip install https://
github.com/django/django/archive/stable/1.7.x.zip.
To read more about what is new in this version of Django, visit https://docs.djangopro
ject.com/en/dev/releases/1.7/. For additional installation instructions, you can also see
the Django guide on installation.
Additional packages will be installed throughout the chapters. Chapters 1, 2, and 3 are
each independent projects and can be treated as separate virtual environments, again
with Django being the only prerequisite. Chapters 4 through 8 comprise one large
project, and the same virtual environment should be used for those chapters.
Web Development
As Django is a web framework, this book assumes you have some basic knowledge of
HTML and CSS. The JavaScript examples are more in depth, and the expected level of
knowledgeisdetailedmoreinthefollowingsection.AbasicunderstandingoftheHTTP
protocol, in particular the usage and purpose of the various HTTP verbs (GET, POST,
PUT, DELETE, etc.), is helpful.
JavaScript
The later chapters in this book make heavy use of JavaScript. You should also be familiar
withwritingJavaScript/jQuery.AdeveloperexperienceddoingDOMmanipulationand
makingAJAXcallswithjQueryshouldbeabletofollowtheexamplesusingBackbone.js.
If you are familiar with another client-side framework such as Angular.js, Ember.js, or
Knockout.js, you will be ahead of the game. This is not meant to be a definitive guide
on Backbone.js. If you are not familiar with working with JavaScript, and Backbone.js
MVC architecture in particular, here are some recommended O’Reilly titles for you to
read:
xiv | Prerequisites
21. • JavaScript: The Definitive Guide, by David Flanagan (2011)
• JavaScript: The Good Parts, by Douglas Crockford (2008)
• JavaScript Patterns, by Stoyan Stefanov (2010)
• Speaking JavaScript, by Axel Rauschmayer (2014)
• Developing Backbone.js Applications, by Addy Osmani (2013)
Browser Support
The examples in this book make use of relatively new HTML5 and CSS3 APIs, and
expectamodernbrowser.Anythingbelowtheseversionshasnotbeentestedthoroughly
and/or may not support the technology that we use in the examples:
• IE 10+
• Firefox 28.0+
• Chrome 33.0+
Youshouldbefamiliarwithusingthedevelopertoolsinyourpreferredbrowsertodebug
potential errors, see network requests, and use the JavaScript console.
Additional Software
Later chapters will make use of two popular databases: PostgreSQL and Redis. Brief
installation instructions are noted in the chapters where needed, but you should refer
to the official documentation for a more complete guide for your system.
PostgreSQL is an open source relational database system that has strong support in the
Django community. Any version of PostgreSQL supported by Django will work for this
book. Django 1.7 supports PostgreSQL 8.4 and higher.
Redis is an open source key/value cache. This book makes use of the pub/sub features
of Redis and requires 2.0 and higher.
Prerequisites | xv
23. CHAPTER 1
The World’s Smallest Django Project
How many of our journeys into using Django have begun with the official polls tutorial?
For many it seems like a rite of passage, but as an introduction to Django it is a fairly
daunting task. With various commands to run and files to generate, it is even harder to
tell the difference between a project and an application. For new users wanting to start
building applications with Django, it begins to feel far too “heavy” as an option for a
web framework. What are some ways we can ease these new users’ fears to create a clean
and simple start?
Let’s take a moment to consider the recommended tasks for starting a Django project.
The creation of a new project generally starts with the startproject command. There
is no real magic to what this command does; it simply creates a few files and directories.
While the startproject command is a useful tool, it is not required in order to start a
Django project. You are free to lay out your project however you like based on what you
want to do. For larger projects, developers benefit from the code organization provided
by the startproject command. However, the convenience of this command shouldn’t
stop you from understanding what it does and why it is helpful.
In this chapter we’ll lay out an example of how to create a simple project using Django’s
basicbuildingblocks.Thislightweight“HelloWorld”projectwillcreateasimpleDjango
application using a single-file approach.
Hello Django
Building a “Hello World” example in a new language or framework is a common first
project.We’veseenthissimplestarterprojectexamplecomeoutoftheFlaskcommunity
to display how lightweight it is as a microframework.
In this chapter, we’ll start by using a single hello.py file. This file will contain all of the
code needed to run our Django project. In order to have a full working project, we’ll
1
24. need to create a view to serve the root URL and the necessary settings to configure the
Django environment.
Creating the View
Django is referred to as a model-template-view (MTV) framework. The view portion
typically inspects the incoming HTTP request and queries, or constructs, the necessary
data to send to the presentation layer.
Inourexamplehello.pyfile,let’screateasimplewaytoexecutea“HelloWorld”response.
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World')
In a larger project, this would typically be in a views.py file inside one of your apps.
However, there is no requirement for views to live inside of apps. There is also no
requirementthatviewsliveinafilecalledviews.py.Thisispurelyamatterofconvention,
but not a requirement on which to base our project’s structure.
The URL Patterns
In order to tie our view into the site’s structure, we’ll need to associate it with a URL
pattern.Forthisexample,theserverrootcanservetheviewonitsown.Djangoassociates
views with their URL by pairing a regular expression to match the URL and any callable
arguments to the view. The following is an example from hello.py of how we make this
connection.
from django.conf.urls import url
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World')
urlpatterns = (
url(r'^$', index),
)
Now this file combines both a typical views.py file and the root urls.py file. Again, it is
worth noting that there is no requirement for the URL patterns to be included in a
urls.py file. They can live in any importable Python module.
Let’s move on to our Django settings and the simple lines we’ll need to make our project
runnable.
2 | Chapter 1: The World’s Smallest Django Project
25. The Settings
Django settings detail everything from database and cache connections to internation‐
alization features and static and uploaded resources. For many developers just getting
started, the settings in Django are a major point of confusion. While recent releases have
worked to trim down the default settings’ file length, it can still be overwhelming.
This example will run Django in debugging mode. Beyond that, Django merely needs
to be configured to know where the root URLs can be found and will use the value
defined by the urlpatterns variable in that module. In this example from hello.py, the
root URLs are in the current module and will use the urlpatterns defined in the pre‐
vious section.
from django.conf import settings
settings.configure(
DEBUG=True,
SECRET_KEY='thisisthesecretkey',
ROOT_URLCONF=__name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
)
...
This example includes a nonrandom SECRET_KEY setting, which
should not be used in a production environment. A secret key must
be generated for the default session and cross-site request forgery
(CSRF) protection. It is important for any production site to have a
random SECRET_KEY that is kept private. To learn more, go to the
documentation at https://docs.djangoproject.com/en/1.7/topics/sign
ing/.
We need to configure the settings before making any additional imports from Django,
as some parts of the framework expect the settings to be configured before they are
imported. Normally, this wouldn’t be an issue since these settings would be included in
their own settings.py file. The file generated by the default startproject command
would also include settings for things that aren’t used by this example, such as the in‐
ternationalization and static resources.
Hello Django | 3
26. Running the Example
Let’s take a look at what our example looks like during runserver. A typical Django
project contains a manage.py file, which is used to run various commands such as cre‐
ating database tables and running the development server. This file itself is a total of 10
lines of code. We’ll be adding in the relevant portions of this file into our hello.py to
create the same abilities manage.py has:
import sys
from django.conf import settings
settings.configure(
DEBUG=True,
SECRET_KEY='thisisthesecretkey',
ROOT_URLCONF=__name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
)
from django.conf.urls import url
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World')
urlpatterns = (
url(r'^$', index),
)
if __name__ == "__main__":
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
Now you can start the example in the command line:
hostname $ python hello.py runserver
Performing system checks...
System check identified no issues (0 silenced).
August 06, 2014 - 19:15:36
Django version 1.7c2, using settings None
4 | Chapter 1: The World’s Smallest Django Project
27. Starting development server at http://7.0.0.1:8000/
Quit the server with CONTROL-C.
and visit http://localhost:8000/ in your favorite browser to see “Hello World,” as seen in
Figure 1-1.
Figure 1-1. Hello World
Now that we have a very basic file structure in place, let’s move on to adding more
elements to serve up our files.
Improvements
This example shows some of the fundamental pieces of the Django framework: writing
views, creating settings, and running management commands. At its core, Django is a
PythonframeworkfortakingincomingHTTPrequestsandreturningHTTPresponses.
What happens in between is up to you.
Django also provides additional utilities for common tasks involved in handling HTTP
requests, such as rendering HTML, parsing form data, and persisting session state.
While not required, it is important to understand how these features can be used in
Improvements | 5
28. your application in a lightweight manner. By doing so, you gain a better understanding
of the overall Django framework and true capabilities.
WSGI Application
Currently, our “Hello World” project runs through the runserver command. This is a
simple server based on the socket server in the standard library. It has helpful utilities
for local development such as auto–code reloading. While it is convenient for local
development, runserver is not appropriate for production deployment security.
The Web Server Gateway Interface (WSGI) is the specification for how web servers
communicate with application frameworks such as Django, and was defined by PEP
333 and improved in PEP 3333. There are numerous choices for web servers that speak
WSGI, including Apache via mod_wsgi, Gunicorn, uWSGI, CherryPy, Tornado, and
Chaussette.
Each of these servers needs a properly defined WSGI application to be used. Django has
an easy interface for creating this application through get_wsgi_application.
...
from django.conf.urls import url
from django.core.wsgi import get_wsgi_application
from django.http import HttpResponse
...
application = get_wsgi_application()
if __name__ == "__main__":
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
This would normally be contained within the wsgi.py file created by the startproject
command. The name application is merely a convention used by most WSGI servers;
each provides configuration options to use a different name if needed.
Now our simple Django project is ready for the WSGI server. Gunicorn is a popular
choice for a pure-Python WSGI application server; it has a solid performance record,
is easy to install, and also runs on Python 3. Gunicorn can be installed via the Python
Package Index (pip).
hostname $ pip install gunicorn
Once Gunicorn is installed, you can run it fairly simply by using the gunicorn com‐
mand.
hostname $ gunicorn hello --log-file=-
[2014-08-06 19:17:26 -0400] [37043] [INFO] Starting gunicorn 19.1.1
[2014-08-06 19:17:26 -0400] [37043] [INFO]
Listening at: http://127.0.0.1:8000 (37043)
6 | Chapter 1: The World’s Smallest Django Project
29. [2014-08-06 19:17:26 -0400] [37043] [INFO] Using worker: sync
[2014-08-06 19:17:26 -0400] [37046] [INFO] Booting worker with pid: 37046
As seen in the output, this example is running using Gunicorn version 19.1.1. The
timestamps shown contain your time zone offset, which may differ depending on your
locale. The process IDs for the arbiter and the worker will also be different.
As of R19, Gunicorn no longer logs to the console by default. Adding
the --log-file=- option ensures that the output will be logged to the
console. You can read more about Gunicorn settings at http://
docs.gunicorn.org/en/19.1/.
As with runserver in Django, the server is listening on http://127.0.0.1:8000/. This
works out nicely and makes an easier configuration for us to work with.
Additional Configuration
While Gunicorn is a production-ready web server, the application itself is not yet pro‐
duction ready, as DEBUG should never be enabled in production. As previously noted,
the SECRET_KEY is also nonrandom and should be made random for additional security.
For more information on the security implications of the DEBUG and
SECRET_KEY settings, please refer to the official Django documenta‐
tion.
This leads to a common question in the Django community: how should the project
manage different settings for development, staging, and production environments?
Django’s wiki contains a long list of approaches, and there are a number of reusable
applications that aim to tackle this problem. A comparison of those applications can be
found on Django Packages. While many of these options can be ideal in some cases,
such as converting the settings.py into a package and creating modules for each envi‐
ronment, they do not line up well with our example’s current single-file setup.
The Twelve Factor App is a methodology for building and deploying HTTP service
applications. This methodology recommends separating configuration and code as well
as storing configurations in environment variables. This makes the configuration easy
to change on the deployment and makes the configuration OS-agnostic.
Improvements | 7
30. Let’s apply this methodology to our hello.py example. There are only two settings that
are likely to change between environments: DEBUG and SECRET_KEY.
import os
import sys
from django.conf import settings
DEBUG = os.environ.get('DEBUG', 'on') == 'on'
SECRET_KEY = os.environ.get('SECRET_KEY', os.urandom(32))
settings.configure(
DEBUG=DEBUG,
SECRET_KEY=SECRET_KEY,
ROOT_URLCONF=__name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
)
As you may notice, the default for DEBUG is True, and the SECRET_KEY will be randomly
generated each time the application is loaded if it is not set. That will work for this toy
example,butiftheapplicationwereusingapieceofDjangothatrequirestheSECRET_KEY
to remain stable, such as the signed cookies, this would cause the sessions to be fre‐
quently invalidated.
Let’s examine how this translates to launching the application. To disable the DEBUG
setting, we need to set the DEBUG environment variable to something other than on. In
a UNIX-derivative system, such as Linux, OS X, or FreeBSD, environment variables are
set on the command line with the export command. On Windows, you’d use set.
hostname $ export DEBUG=off
hostname $ python hello.py runserver
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.
As you can see from the error, the ALLOWED_HOSTS setting isn’t configured by our ap‐
plication. ALLOWED_HOSTS is used to validate incoming HTTP HOST header values and
should be set to a list of acceptable values for the HOST. If the application is meant to
serve example.com, then ALLOWED_HOSTS should allow only for clients that are request‐
ing example.com. If the ALLOWED_HOSTS environment variable isn’t set, then it will allow
requests only for localhost. This snippet from hello.py illustrates.
import os
import sys
from django.conf import settings
8 | Chapter 1: The World’s Smallest Django Project
31. DEBUG = os.environ.get('DEBUG', 'on') == 'on'
SECRET_KEY = os.environ.get('SECRET_KEY', os.urandom(32))
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split(',')
settings.configure(
DEBUG=DEBUG,
SECRET_KEY=SECRET_KEY,
ALLOWED_HOSTS=ALLOWED_HOSTS,
ROOT_URLCONF=__name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
)
With our ALLOWED_HOSTS variable set, we now have validation for our incoming HTTP
HOST header values.
For a complete reference on the ALLOWED_HOSTS setting, see the offi‐
cial Django documentation.
Outside the development environment, the application might need to serve multiple
hosts, such as localhost and example.com, so the configuration allows us to specify
multiple hostnames separated by commas.
hostname $ export DEBUG=off
hostname $ export ALLOWED_HOSTS=localhost,example.com
hostname $ python hello.py runserver
...
[06/Aug/2014 19:45:53] "GET / HTTP/1.1" 200 11
This gives us a flexible means of configuration across environments. While it would be
slightly more difficult to change more complex settings, such as INSTALLED_APPS or
MIDDLEWARE_CLASSES, that is in line with the overall methodology, which encourages
minimal differences between environments.
If you want to make complex changes between environments, you
should take time to consider what impact that will have on the testa‐
bility and deployment of the application.
Improvements | 9
32. We can reset DEBUG to the default by removing the environment variable from the shell
or by starting a new shell.
hostname $ unset DEBUG
Reusable Template
So far this example has centered on rethinking the layout created by Django’s
startproject command. However, this command also allows for using a template to
provide the layout. It isn’t difficult to transform this file into a reusable template to start
future projects using the same base layout.
A template for startproject is a directory or zip file that is rendered as a Django
template when the command is run. By default, all of the Python source files will be
rendered as a template. The rendering is passed project_name, project_directory,
secret_key, and docs_version as the context. The names of the files will also be ren‐
dered with this context. To transform hello.py into a project template (project_name/
project_name.py), the relevant parts of the file need to be replaced by these variables.
import os
import sys
from django.conf import settings
DEBUG = os.environ.get('DEBUG', 'on') == 'on'
SECRET_KEY = os.environ.get('SECRET_KEY', '{{ secret_key }}')
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split(',')
settings.configure(
DEBUG=DEBUG,
SECRET_KEY=SECRET_KEY,
ALLOWED_HOSTS=ALLOWED_HOSTS,
ROOT_URLCONF=__name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
)
from django.conf.urls import url
from django.core.wsgi import get_wsgi_application
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World')
10 | Chapter 1: The World’s Smallest Django Project
33. urlpatterns = (
url(r'^$', index),
)
application = get_wsgi_application()
if __name__ == "__main__":
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
Nowlet’ssavethisfileasproject_name.pyinadirectorycalledproject_name.Also,rather
than using os.urandom for the SECRET_KEY default, this code will generate a random
secret to be the default each time a new project is created. This makes the SECRET_KEY
default stable at the project level while still being sufficiently random across projects.
To use the template with startproject, you can use the --template argument.
hostname $ django-admin.py startproject foo --template=project_name
This should create a foo.py inside a foo directory, which is now ready to run just like the
original hello.py.
As outlined in this example, it is certainly possible to write and run a Django project
withouthavingtousethe startproject command.Thedefaultsettingsandlayoutused
by Django aren’t appropriate for every project. The --template option for
startproject can be used to either expand on these defaults or to trim them down, as
you’ve seen in this chapter.
AswithanyPythonproject,therecomesapointwhereorganizingthecodeintomultiple
modules is an important part of the process. For a sufficiently focused site, with only a
handful of URLs, our “Hello World” example may be a reasonable approach.
What is also interesting about this approach is that it isn’t immediately obvious that
Django has a templating engine or an object-relational mapper (ORM) built in. It is
clear that you are free to choose whatever Python libraries you think best solve your
problem.YounolongerhavetousetheDjangoORM,astheofficialtutorialmightimply.
Instead, you get to use the ORM if you want. The project in the next chapter will expand
on this single-file example to provide a simple HTTP service and make use of more of
the utilities that come with Django.
Improvements | 11
35. CHAPTER 2
Stateless Web Application
Most Django applications and tutorials center on some variety of user-generated con‐
tent, such as to-do lists, blogs, and content management systems. This isn’t surprising
given Django’s original roots in journalism.
In 2005, Django was originally developed at World Online in Lawrence, Kansas, as a
way for reporters to quickly create content for the Web. Since then, it has been used by
publishing organizations such as the Washington Post, the Guardian, PolitiFact, and
the Onion. This aspect of Django may give the impression that its main purpose is
content publishing, or that Django itself is a content management system. With large
organizations such as NASA adopting Django as their framework of choice, however,
Django has obviously outgrown its original purpose.
In the previous chapter we created a minimal project that made use only of Django’s
coreHTTPhandlingandURLrouting.Inthischapterwewillexpanduponthatexample
to create a stateless web application that uses more of Django’s utilities, such as input
validation, caching, and templates.
Why Stateless?
HTTP itself is a stateless protocol, meaning each request that comes to the server is
independent of the previous request. If a particular state is needed, it has to be added
at the application layer. Frameworks like Django use cookies and other mechanisms to
tie together requests made by the same client.
Alongwithapersistentsessionstoreontheserver,theapplicationcanthenhandletasks,
such as holding user authentication across requests. With that comes a number of chal‐
lenges, as this consistent state reads, and potentially writes, on every request in a dis‐
tributed server architecture.
13
36. As you can imagine, a stateless application does not maintain this consistent state on a
server. If authentication or other user credentials are required, then they must be passed
by the client on every request. This often makes scaling, caching, and load balancing
with stateless applications much easier. You can also make stateless applications easily
linkable because the URL can convey most of these states. There are two options we can
take, which we’ll outline in the next section: reusable apps and composable services.
Reusable Apps Versus Composable Services
Much of the focus in the Django community is about building reusable applications
that can be installed and configured into any Django project. However, large applica‐
tions with different components often have a fairly complex architectural structure.
An approach to combat this complexity is to break large websites into composable
services—that is, smaller services that communicate with one another. This doesn’t
mean that they can’t and won’t share code at some point. It does mean, however, that
each service can then be configured and built separately.
Stateless components, such as REST APIs, are great candidates for breaking out into
separate Django projects that can be deployed and tuned independently. Let’s build on
our Chapter 1 project by creating a placeholder image server using the two techniques
just described with Django.
Placeholder Image Server
Placeholder images are frequently used in application prototypes, example projects, or
testing environments. A typical placeholder image service will take a URL that indicates
the size of the image and generate that image. The URL may contain additional infor‐
mation, such as the color of the image or text to display within the image. Since every‐
thing that is needed to construct the requested image is contained within the URL, and
there’s little need for authentication, this makes a good candidate for a stateless appli‐
cation.
Start by creating a new project called placeholder with the startproject using the
project_name template created in Chapter 1.
hostname $ django-admin.py startproject placeholder --template=project_name
This will generate a placeholder.py file for us to begin building our service. If you have
used the project template correctly, placeholder.py should look like this:
import os
import sys
from django.conf import settings
DEBUG = os.environ.get('DEBUG', 'on') == 'on'
14 | Chapter 2: Stateless Web Application
37. SECRET_KEY = os.environ.get('SECRET_KEY',
'%jv_4#hoaqwig2gu!eg#^ozptd*a@88u(aasv7z!7xt^5(*i&k')
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split(',')
settings.configure(
DEBUG=DEBUG,
SECRET_KEY=SECRET_KEY,
ALLOWED_HOSTS=ALLOWED_HOSTS,
ROOT_URLCONF=__name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
)
from django.conf.urls import url
from django.core.wsgi import get_wsgi_application
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World')
urlpatterns = (
url(r'^$', index),
)
application = get_wsgi_application()
if __name__ == "__main__":
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
The SECRET_KEY setting will be different from this published ver‐
sion, as it is randomly generated by the startproject command.
With our initial settings in place, we can now begin to write our views and start building
out the pages to create these responses.
Placeholder Image Server | 15
38. Views
Since this application will be simple, we will need only two views to generate our re‐
sponses. The first view will render the placeholder images based on their requested
width and height. The other view will render the home page content, which explains
how the project works and renders a few example images. Because we used Django’s --
template flag when running the startproject command, the index has already been
generated (as shown in this snippet from placeholder.py) and will need to be adapted
later.
...
def placeholder(request, width, height):
# TODO: Rest of the view will go here
return HttpResponse('Ok')
def index(request):
return HttpResponse('Hello World')
...
With these simple views in place, we should now think about the URL structure for
displaying our placeholders.
URL Patterns
When opening your generated placeholder.py file, you’ll notice that there is a URL pat‐
tern for the server root. We’ll also need a route to the placeholder view we just created.
The stub of the placeholder view will take two arguments: width and height. As men‐
tioned previously, those parameters will be captured by the URL and passed to the view.
Since they will only ever be integers, we’ll want to make sure to enforce them by the
URL. Since URL patterns in Django use regular expressions to match the incoming
URL, we’ll be able to easily pass in those parameters.
Captured pattern groups are passed to the view as positional arguments, and named
groups are passed as keyword arguments. Named groups are captured using the ?P
syntax, and any digit characters are matched by using [0-9].
This snippet from placeholder.py shows how your URL patterns will be laid out to gen‐
erate those values:
...
urlpatterns = (
url(r'^image/(?P<width>[0-9]+)x(?P<height>[0-9]+)/$', placeholder,
name='placeholder'),
url(r'^$', index, name='homepage'),
)
...
16 | Chapter 2: Stateless Web Application
39. Withthesepatternsinplace,incomingrequeststotheURL/image/30x25/willberouted
totheplaceholder viewandpassinthosevalues(e.g.,width=30 andheight=25).Along
with the new route for the placeholder view, the name homepage has been added to the
index router. We will also see how naming these URL patterns, while a good practice in
general, will be especially useful when we begin to build the templates later.
Placeholder View
Along with the original HTTP request, the placeholder view should accept two integer
arguments for the image’s height and width values. Though the regular expression will
ensure that the height and width consist of digits, they will be passed to the view as
strings. The view will need to convert them and may also want to validate that they are
a manageable size. We can easily do this by validating user input with Django forms.
Typically forms are used to validate POST and GET content, but they can also be used
tovalidateparticularvaluesfromtheURL,orthosestoredincookies.Hereisanexample
from placeholder.py of a simple form to validate the height and width of an image:
...
from django import forms
from django.conf.urls import url
...
class ImageForm(forms.Form):
"""Form to validate requested placeholder image."""
height = forms.IntegerField(min_value=1, max_value=2000)
width = forms.IntegerField(min_value=1, max_value=2000)
def placeholder(request, width, height):
...
As you can see, the first thing the view should do is validate the requested image size.
Iftheformisvalid,thentheheightandwidthcanbeaccessedintheform’scleaned_data
attribute. At this point, the height and width will be converted to integers, and the view
can be sure that the values are between 1 and 2000. We’ll also need to add validation to
the form to send an error message if the values are incorrect, as shown in this excerpt
from placeholder.py.
...
from django import forms
from django.conf.urls import url
from django.core.wsgi import get_wsgi_application
from django.http import HttpResponse, HttpResponseBadRequest
class ImageForm(forms.Form):
"""Form to validate requested placeholder image."""
Placeholder View | 17
40. height = forms.IntegerField(min_value=1, max_value=2000)
width = forms.IntegerField(min_value=1, max_value=2000)
def placeholder(request, width, height):
form = ImageForm({'height': height, 'width': width})
if form.is_valid():
height = form.cleaned_data['height']
width = form.cleaned_data['width']
# TODO: Generate image of requested size
return HttpResponse('Ok')
else:
return HttpResponseBadRequest('Invalid Image Request')
...
If the form isn’t valid, the view will send an error response to the client. Here the view
returns an HttpResponseBadRequest, which is a subclass of HttpResponse, and sends
a 400 Bad Request response.
Image Manipulation
The view now has the ability to accept and clean the height and width requested by the
client, but it does not yet generate the actual image. To handle image manipulation in
Python, you need to have Pillow installed as follows:
hostname $ pip install Pillow
By default, the install will try to compile Pillow from the source. If
you do not have a compiler installed for your environment, or you
are missing the necessary headers, it can fail to install. For installa‐
tion notes on various platforms, visit https://
pillow.readthedocs.org/en/latest/installation.html.
Creating an image with Pillow requires two arguments: the color mode and the size as
a tuple. This view from placeholder.py will use the RGB mode and the size from the form’s
cleaned data values. There is a third argument, which is not required, that sets the color
of the image. By default in Pillow, every pixel of the image will be black.
...
from io import BytesIO
from PIL import Image
...
class ImageForm(forms.Form):
"""Form to validate requested placeholder image."""
height = forms.IntegerField(min_value=1, max_value=2000)
width = forms.IntegerField(min_value=1, max_value=2000)
18 | Chapter 2: Stateless Web Application
41. def generate(self, image_format='PNG'):
"""Generate an image of the given type and return as raw bytes."""
height = self.cleaned_data['height']
width = self.cleaned_data['width']
image = Image.new('RGB', (width, height))
content = BytesIO()
image.save(content, image_format)
content.seek(0)
return content
def placeholder(request, width, height):
form = ImageForm({'height': height, 'width': width})
if form.is_valid():
image = form.generate()
return HttpResponse(image, content_type='image/png')
else:
return HttpResponseBadRequest('Invalid Image Request')
...
A new generate method has been added to the ImageForm to encapsulate the
logic of building the image. It takes one argument for the image format, which
defaults to PNG, and returns the image contents as bytes.
Using the width and height given by the URL and validated by the form, a new
image is constructed using the Image class from Pillow.
The view calls form.generate to get the constructed image, and the bytes for
the image are then used to construct the response body.
The form then validates the size to prevent requesting too large of an image and con‐
suming too many resources on the server. Once the image has been validated, the view
successfully returns the PNG image for the requested width and height. The image
content is sent to the client without writing it to the disk.
However, an all-black image, with no sizing information, is not a very stylish or useful
placeholder.WithPillow wecanaddthistexttotheimageusingtheImageDraw module,
as shown in this snippet from placeholder.py.
...
from PIL import Image, ImageDraw
...
class ImageForm(forms.Form):
...
def generate(self, image_format='PNG'):
"""Generate an image of the given type and return as raw bytes."""
height = self.cleaned_data['height']
width = self.cleaned_data['width']
image = Image.new('RGB', (width, height))
Placeholder View | 19
42. draw = ImageDraw.Draw(image)
text = '{} X {}'.format(width, height)
textwidth, textheight = draw.textsize(text)
if textwidth < width and textheight < height:
texttop = (height - textheight) // 2
textleft = (width - textwidth) // 2
draw.text((textleft, texttop), text, fill=(255, 255, 255))
content = BytesIO()
image.save(content, image_format)
content.seek(0)
return content
...
generate now uses ImageDraw to add a text overlay if it will fit.
Using ImageDraw, the form uses the current image to create text showing the width and
height on the image,
Now that we have our valid placeholder image in place, let’s add some caching to help
minimize requests to the server.
Adding Caching
The placeholder image view currently regenerates the image and serves it each time the
view is requested. Since the width and height of the image are set via the original, we
are constantly making unnecessary requests to our server.
One way to avoid this repetition is to use caching. There are two options to think about
when you’re determining how to utilize caching for this service: server-side and client-
side. For server-side caching, you can easily use Django’s cache utilities. This will trade
memory usage to store the cached values while saving the CPU cycles required to gen‐
erate the images, as shown in this excerpt from placeholder.py.
...
from django.conf.urls import url
from django.core.cache import cache
...
class ImageForm(forms.Form):
...
def generate(self, image_format='PNG'):
"""Generate an image of the given type and return as raw bytes."""
height = self.cleaned_data['height']
width = self.cleaned_data['width']
key = '{}.{}.{}'.format(width, height, image_format)
content = cache.get(key)
if content is None:
image = Image.new('RGB', (width, height))
draw = ImageDraw.Draw(image)
text = '{} X {}'.format(width, height)
textwidth, textheight = draw.textsize(text)
20 | Chapter 2: Stateless Web Application
43. if textwidth < width and textheight < height:
texttop = (height - textheight) // 2
textleft = (width - textwidth) // 2
draw.text((textleft, texttop), text, fill=(255, 255, 255))
content = BytesIO()
image.save(content, image_format)
content.seek(0)
cache.set(key, content, 60 * 60)
return content
A cache key is generated that depends on the width, height, and image format.
Before a new image is created, the cache is checked to see if the image is already
stored.
When there is a cache miss and a new image is created, the image is cached using
the key for an hour.
Django defaults to using a process-local, in-memory cache, but you could use a different
backend—such as Memcached or the file system—by configuring the CACHES setting.
A complementary approach is to focus on the client-side behavior and make use of the
browser’s built-in caching. Django includes an etag decorator for generating and using
theETagheadersfortheview.Thedecoratortakesasingleargument,whichisafunction
to generate the ETag header from the request and view arguments. Here is an example
from placeholder.py of how we would add that to our view:
import hashlib
import os
...
from django.http import HttpResponse, HttpResponseBadRequest
from django.views.decorators.http import etag
...
def generate_etag(request, width, height):
content = 'Placeholder: {0} x {1}'.format(width, height)
return hashlib.sha1(content.encode('utf-8')).hexdigest()
@etag(generate_etag)
def placeholder(request, width, height):
...
generate_etag is a new function that takes the same arguments as the
placeholder view. It uses hashlib to return an opaque ETag value, which will
vary based on the width and height values.
The generate_etag function will be passed to the etag decorator on the
placeholder view.
Placeholder View | 21
44. With this decorator in place, the server will need to generate the image the first time
the browser requests it. On subsequent requests, if the browser makes a request with
the matching ETag, the browser will receive a 304 Not Modified response for the image.
The browser will use the image from the cache and save bandwidth and time to regen‐
erate the HttpResponse.
This view generates an image based only on the width and height. If
other features were added, such as the background color or the im‐
age text, then the ETag generation would also need to be updated to
take these into account.
The django.middleware.common.CommonMiddleware, which is enabled in the
MIDDLEWARE_CLASSES setting, also has support for generating and using ETags if the
USE_ETAGS setting is enabled. However, there is a difference between how the middle‐
ware and the decorator work. The middleware will calculate the ETag based on the md5
hash of the response content. That requires the view to do all the work to generate the
content in order to calculate the hash. The result is the same in that the browser will
receive a 304 Not Modified response and the bandwidth will be saved. Using the etag
decorator has the advantage of calculating the ETag prior to the view being called, which
will also save on the processing time and resources.
The following is the completed placeholder view for placeholder.py, along with the
form and decorator functions:
...
class ImageForm(forms.Form):
"""Form to validate requested placeholder image."""
height = forms.IntegerField(min_value=1, max_value=2000)
width = forms.IntegerField(min_value=1, max_value=2000)
def generate(self, image_format='PNG'):
"""Generate an image of the given type and return as raw bytes."""
height = self.cleaned_data['height']
width = self.cleaned_data['width']
key = '{}.{}.{}'.format(width, height, image_format)
content = cache.get(key)
if content is None:
image = Image.new('RGB', (width, height))
draw = ImageDraw.Draw(image)
text = '{} X {}'.format(width, height)
textwidth, textheight = draw.textsize(text)
if textwidth < width and textheight < height:
texttop = (height - textheight) // 2
textleft = (width - textwidth) // 2
draw.text((textleft, texttop), text, fill=(255, 255, 255))
content = BytesIO()
22 | Chapter 2: Stateless Web Application
45. image.save(content, image_format)
content.seek(0)
cache.set(key, content, 60 * 60)
return content
def generate_etag(request, width, height):
content = 'Placeholder: {0} x {1}'.format(width, height)
return hashlib.sha1(content.encode('utf-8')).hexdigest()
@etag(generate_etag)
def placeholder(request, width, height):
form = ImageForm({'height': height, 'width': width})
if form.is_valid():
image = form.generate()
return HttpResponse(image, content_type='image/png')
else:
return HttpResponseBadRequest('Invalid Image Request')
...
With our placeholder view ready, let’s go back and build out our home page view to
complete our application.
Creating the Home Page View
The home page will render a basic HTML template to explain how the project works
and include some sample images. Up to this point, Django has not been configured to
render templates. It also has not been configured to serve static resources, such as Java‐
Script,CSS,andtemplates.Let’saddthenecessarysettingstoservethosestaticresources:
TEMPLATE_DIRS and STATICFILES_DIRS.
Adding Static and Template Settings
Django’s template loader will automatically discover templates and static resources in‐
sidetheinstalledapps.SincethisprojectdoesnotincludeanyDjangoapplications,these
locations need to be configured with the TEMPLATE_DIRS and STATICFILES_DIRS set‐
tings. django.contrib.staticfiles will also need to be added to the IN
STALLED_APPS for the {% static %} tag and collectstatic commands to be available.
Here is an example of how your directory structure should look at this point:
placeholder/
placeholder.py
The templates and static resources would fit nicely in directories next to placehold‐
er.py, as in:
placeholder/
placeholder.py
Creating the Home Page View | 23
46. templates/
home.html
static/
site.css
To avoid hardcoding these paths, we’ll be constructing them relative to the placehold‐
er.py file using the os module from the Python standard library.
import hashlib
import os
import sys
from django.conf import settings
DEBUG = os.environ.get('DEBUG', 'on') == 'on'
SECRET_KEY = os.environ.get('SECRET_KEY',
'%jv_4#hoaqwig2gu!eg#^ozptd*a@88u(aasv7z!7xt^5(*i&k')
BASE_DIR = os.path.dirname(__file__)
settings.configure(
DEBUG=DEBUG,
SECRET_KEY=SECRET_KEY,
ROOT_URLCONF=__name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
INSTALLED_APPS=(
'django.contrib.staticfiles',
),
TEMPLATE_DIRS=(
os.path.join(BASE_DIR, 'templates'),
),
STATICFILES_DIRS=(
os.path.join(BASE_DIR, 'static'),
),
STATIC_URL='/static/',
...
Now let’s add a simple template structure to finish out this example project with a clean
frontend interface.
Home Page Template and CSS
The purpose of the home page for this application is to demonstrate how to use the
placeholder images with some brief documentation and examples. It should be saved
24 | Chapter 2: Stateless Web Application
47. as templates/home.html next to placeholder.py. We’ll also add in the src reference to our
placeholder route to request those images.
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Django Placeholder Images</title>
<link rel="stylesheet" href="{% static 'site.css' %}" type="text/css">
</head>
<body>
<h1>Django Placeholder Images</h1>
<p>This server can be used for serving placeholder
images for any web page.</p>
<p>To request a placeholder image of a given width and height
simply include an image with the source pointing to
<b>/placeholder/<width>x<height>/</b>
on this server such as:</p>
<pre>
<img src="{{ example }}" >
</pre>
<h2>Examples</h2>
<ul>
<li><img src="{% url 'placeholder' width=50 height=50 %}"></li>
<li><img src="{% url 'placeholder' width=100 height=50 %}"></li>
<li><img src="{% url 'placeholder' width=50 height=100 %}"></li>
<ul>
</body>
</html>
Here are some simple styles to add to site.css to help create a clean layout. Also, don’t
forget to save this file in your static/ folder, as previously outlined in your
STATICFILES_DIRS setting:
body {
text-align: center;
}
ul {
list-type: none;
}
li {
display: inline-block;
}
Creating the Home Page View | 25
48. You should save this as static/site.css next to placeholder.py, as outlined in the previous
section. Finally, we need to update the index view in placeholder.py to render this tem‐
plate:
...
from django.core.cache import cache
from django.core.urlresolvers import reverse
from django.core.wsgi import get_wsgi_application
from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import render
from django.views.decorators.http import etag
...
def index(request):
example = reverse('placeholder', kwargs={'width': 50, 'height':50})
context = {
'example': request.build_absolute_uri(example)
}
return render(request, 'home.html', context)
...
The updated index view builds an example URL by reversing the placeholder
view, and passes it to the template context.
The home.html template is rendered using the render shortcut.
Completed Project
Now you should have a completed placeholder.py file that looks similar to the following
one. Along with home.html and site.css from the previous section, it completes our
simple placeholder image service using Django:
import hashlib
import os
import sys
from io import BytesIO
from PIL import Image, ImageDraw
from django.conf import settings
DEBUG = os.environ.get('DEBUG', 'on') == 'on'
SECRET_KEY = os.environ.get('SECRET_KEY',
'%jv_4#hoaqwig2gu!eg#^ozptd*a@88u(aasv7z!7xt^5(*i&k')
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split(',')
BASE_DIR = os.path.dirname(__file__)
settings.configure(
DEBUG=DEBUG,
26 | Chapter 2: Stateless Web Application
51. choir of young voices, and bid all prepare. A sacrifice will be offered
to Mitzor; the Great White Glory must be appeased.”
Alan and Sir John were very mystified over the whole scene. These
Jovians did not seem to understand Death—yet they spoke of
sacrifice!
“I am sorry, my son,” said the Jkak. “I can save nothing for you. All
must be burnt and offered to Mitzor. Come now, I will draw a ring
around the contaminated spot, and we will witness the destruction
from without.”
Sir John and Alan were both loth to have the Argenta burnt—but
being dependent on the Jovians for their entire future, they were
unable to demur. With a silent prayer for the friend who had given
his life for them, they left the ship and stood some way off. After an
interminable time of waiting, a mighty blast of music burst on their
ears, and they saw a procession of etheric bhors coming towards
them. The first stopped, and Misrath the High Priest alighted,
followed by priests and acolytes in quaint garments of ecclesiastical
cut.
A procession formed—two acolytes with censers led the way, and
wafted the glorious perfume from side to side. Then followed one of
the most mystical and picturesque ceremonies it was possible to
imagine. Almost of Mosaic grandeur, it thrilled the watchers. They
were unable to understand what was being said—all was in the
language of the Keemarnians—but the meaning was plain. The High
Priest offered the Argenta and its contents to Mitzor, the Great White
Glory. He offered it, with its fine workmanship, its precious metals—
and its body of sin. He asked that through the mediation of the
sacrifice, any evil might be averted, that the entrance of Death might
bring. He consecrated the Argenta to Mitzor—he consecrated the
ground it contaminated. He poured the “waters of purity” across its
bow, and named it “Meeka,” the Bringer of Knowledge.
Then the Argenta was sprayed from stem to stern with a milky
fluid that dried like little curds all over the vessel. A torch was lighted
and applied to the ship. Little flames ran along meeting each other
until they merged into one great whole; there was a roar and a noise
like thunder, and the Argenta, the hobby of a life time, the fruit of
patient labour, was no more!
52. Sir John watched with a set face, but as the fire died out, and he
saw that the whole had been swallowed up, had consumed itself
entirely,—he crumpled up, and lay inert upon the ground.
53. CHAPTER VI
THE SACRAMENT OF SCHLERIK-ITATA
Alan bent over his uncle, but the High Priest waved him away.
“Touch him not,” said he sternly, and such command rang in his
tones, that Alan stepped back involuntarily.
Again the scene was repeated—Sir John was prayed over, sprayed
with the “waters of purity,” and incensed. As the sweet fumes found
their way up his nostrils, he stirred. Alan rushed to him and
embraced him. “It was only foolishness, Alan,” said he brokenly. “But
the Argenta—my ship—I was so proud of her. Masters, you know how
I felt? She was my all in my days of sorrow. And in my days of joy,
when reunited we sailed in her, she was my joy.”
“I understand, Uncle John. But try not to mind—when one is in
Rome—you know the rest. We are in Jupiter and we must do as the
Jovians wish.”
Persoph the Jkak, came up to them. “Nay, grieve not,” said he
kindly. “We have cleared this place of sin. An air bird to take the
place of the one that has gone shall be placed at your disposal. Go
you home. Cards will be brought you for the Sacrament of Schlerik-
itata. I beg of you all—attend it. Nay, I command you. We will meet
again within eight Kymos. Farewell. Farewell.”
Waz-Y-Kjesta, motioned to their bhor. “Come, my friend,” said he.
“I will drive you back another way—we will drive along the shores of
the secti, and watch the breakers roll in.” The sea shore was
wonderful; the sea was blue, a deep, deep blue, and the breakers,
flecked with foam, rolled in to a golden shore. They passed bays,
promontories, caves and rocks—and they found the drive of
bewildering beauty.
Alan asked, “What is the Sacrament of Sch—”
“Schlerik-itata?” supplemented the Waz.
54. “Yes.”
“My friend, you must wait until you witness it. You will understand
us more fully when you have been to the home of Ak-Marn. Now to-
night, there is a small party being given by Kulmervan and his fellow
students at the Observatory. I have been asked to bring you all. Will
you come?”
“With pleasure,” said Alan.
“The Jkak is sending you all a complete outfit, my friend. Your
clothes are old, travel-stained and torn—they are sombre too. If you
accept his present, wear to-night your brightest garments.”
“Will you help me to adjust them?” asked Alan.
The Waz drew himself up with a haughty air, but it as soon passed.
“I was forgetting, my friend, that you know not our customs. The
serving men will assist you. When you reach home, you will find your
house fully staffed, and Quori, a most efficient steward and adviser.”
“What about meeting to-night for the party?”
“I will call for you as the Kymo sinks. You will have bhors sufficient
for your use.”
When they reached home they found a note awaiting them from
Mavis, asking them to come over and have lunch with her and
Desmond, and they walked through the garden to the other house.
Mavis was waiting for them, her cheeks dimpling and her eyes
sparkling. “It’s a wonderful country,” said she. “I’ve nothing to do all
day; the cooking and cleaning seem to go by clockwork. Morkaba is
Baby’s personal attendant and mine; she has arranged my frock.
How do you like it?” and she twirled round on one foot showing the
soft draperies of Keemarnian dress.
It was of a soft green, embroidered with coloured silks and her hair
was left loose flowing around her shoulders, and caught above her
ears by a narrow fillet of gold that gleamed as she tossed her head.
“I like it much better than the frumpy old English fashions,” said
she. “Desmond is not quite ready yet—he will look splendid.”
“We shall change later,” said Sir John, “and I shall be glad to get
out of these stuffy and dirty garments. All the same I don’t fancy
myself a cross between an imitation gladiator and a stained glass
twelfth century saint.”
55. They thoroughly enjoyed their meal; eggs served in a wonderful
salad of fruit and vegetables proved to be the staple part, and this
course was followed by a baked grain, similar to barley, but of a
bright green colour, deliciously creamy and sweet. There was milk to
drink, and plenty of heavy cream.
“They seem to be almost vegetarians here,” said Mavis, “for
although we have had plenty of milk, eggs and cream, I have not seen
a sign of fish or meat.”
“All the better,” said Sir John, “after all that tinned stuff while we
were on the Argenta—ugh!”
They drove in state to the students’ party. The Waz had constituted
himself their guide, and they were very thankful for his services. The
large ground floor of the Observatory had been converted into a
veritable bower of roses. At one end, almost hidden by flowers, were
the musicians—playing dreamy music on soft-toned, stringed
instruments.
The Host in Chief, Kulmervan, with Waiko, stood on a raised dais
at one end and received their guests, who were all announced by an
usher who wore a kilt-like shirt and a flowing cape. As the strangers
entered he announced from a card they gave him, first in his own
language and then in English, “Sir John, Alan, Desmond, Masters,
and Mavis.” No surnames were known on Jupiter, and so far they
possessed no Keemarnian title. To Sir John they gave his prefix,
although they did not quite understand it.
A great silence reigned when the announcement was made—
Kulmervan left the dais and advanced toward his guests, and this
mark of homage was acknowledged by clamorous cheers from all the
others who were present.
“Welcome,” said he. “I witnessed your descent upon our land.
Indeed, it was I who helped to focus our ray of attraction upon your
vessel and helped to draw you into our atmosphere.”
“What are your rays?” asked Alan. “Surely you had never any cause
to use one before?”
“Indeed, yes, my friend. Some time ago, some of our Keemarnians,
while experimenting in the Heavens, found themselves outside our
atmosphere. They never returned. Across the roadway between the
red planet ‘Mydot’—Mars I think you call it—and ourselves, are many
56. rapidly moving meteoric bodies. We fear that our gallant brothers
met one of these, and were destroyed. Many men of science went
after these lost ones but none ever returned. Through our wonderful
glass, we saw one of our air birds in space; it was unable to reach
home. Then was the great magnetic ray discovered. In the shortest
space of time it was perfected, and played on the silent air bird.
Gradually it was drawn nearer and nearer to our shores until it was
within our atmosphere, and was able to land in safety. Since that
time, if air birds venture too high, we have nearly always been able to
save the adventurous spirits, and in your case, we brought you safely
here.”
“It’s a wonderful invention,” said Sir John, “and I can imagine
would have been of immense value to our airmen on earth.”
Kulmervan then presented them to Waiko, and Mavis was led to a
seat of honour on the dais.
They spent a most enjoyable time, and the whole entertainment
was very like what they were accustomed to on earth. Games were
played,—games with balls and racquets, and balls and hoops, and
between the games there was singing and dancing.
Refreshments were served in a hall adjoining, and consisted
mainly of luscious fruits and dainty cakes and pastries. The many
Keemarnians they met, invited them in turn to parties and
entertainments, and they felt they had more invitations than they
could safely accept. “Never accept,” whispered Waz-Y-Kjesta to them
all, “unless you mean to honour your host with your presence. A
refusal never offends, but to accept and then to disappoint, is
unforgivable.” Suddenly in the middle of the dancing a trumpet blew
loud and clear. The band ceased and the couples stood still. Then
rang out a fanfare of royal welcome, and the guests rushed to the
entrance hall in great excitement, waving and cheering. “It must be
some one of importance who is coming,” said Desmond. “Perhaps it
is the Rorka,” suggested Mavis. There was a roll of drums, and then,
on a litter carried by six stalwart men, entered a girl of perhaps
eighteen years. The cortége stopped and Kulmervan bent low before
her, and kissed her proffered hand. She bowed ever so slightly, and
he assisted her from her cushioned throne. She stood beside him,
and proved to be quite small, not more than five feet in height, but of
a beauty almost indescribable. She was very fair and fragile. Her eyes
57. were purple-blue fringed with long, black lashes. Her fillet was of
gold, and was enriched with gems the colour of her eyes, while her
robe of blue hung in folds about her. Perhaps it was her lips that
impressed the watchers most. A perfect bow—they were of a vivid
scarlet that contrasted strangely with the delicate pink flush of her
cheeks. Self possessed, calm and regal she looked as she graciously
acknowledged the plaudits of the guests.
“Who is she, Alan?” asked Mavis. But he was unconscious of her
question, he could only gaze and gaze at the beautiful apparition who
had come so unexpectedly upon the scene.
Waiko bent in turn before the stranger who whispered something
to him. Immediately he came toward Mavis. “We are honoured to-
night,” said he. “The Ipso-Rorka Chlorie has journeyed from Pyrmo
to welcome you. She heard of your presence and came at once.”
“Who is she?” asked Mavis.
“Why the highest lady in the land—the only child of our Rorka.”
Mavis went toward where the girl stood, and the Ipso-Rorka held
out both her hands to the English girl. “Welcome,” said she, in a
voice musical and low. “I hear you start soon to honour the Rorka,
my father, with a visit. May I welcome you first?” In turn the others
were presented to her, but her attention was all for Mavis—it was
Mavis the woman she wanted to know.
And Alan? He had seen his ideal! Years before, he wondered
whether he would ever meet her—and now he had. And a King’s
daughter! And he a stranger in a strange world! How dare he even lift
his eyes toward her. Yet he dared—and his pulses leapt madly as his
eyes feasted on her beauty. Not once did she address him—not once
did she even seem to notice him. Chlorie put her hand lightly on
Desmond’s arm. “I will dance with you,” said she smiling, and Alan
watched them lead the merry throng of dancing couples. The demon
of jealousy, earth jealousy, was in his heart.
“Why are you looking so—how can I put it—so sad?” asked
Kulmervan.
Alan laughed. “He has a wife,” he muttered. “Why does he take her
from others?”
“But she has honoured him. It is not for us to choose for the Ipso-
Rorka,” said Kulmervan.
58. “Yes, but she is so beautiful, so sweet, so glorious,” began Alan.
Then he stopped suddenly. “Oh,” he continued, “what do you people
of Jupiter know of love or hate? Your lives are too quiet, too
humdrum to know aught of passion—”
“Teach me! Teach me!” cried Kulmervan leaning toward him.
“Your face is drawn—your eye hard. Yet you look as if you could
battle with the world. What is it?”
“Love and hate,” said Alan grimly. Then he laughed. “What a fool I
am. Desmond is my cousin; we love each other like brothers. He has
won Mavis—why should he not dance with the Ipso-Rorka? Mavis
does not mind.”
But Kulmervan turned away in silence. Knowledge had come to
him in a curious way. He saw passion, love, hatred, anger, jealousy
all raging within a human heart. Unconsciously the feelings were
photographed upon his too sensitive mind. Love that had only
smouldered was now born in all its fury for the Princess Chlorie, the
fair. And with love was born the twin, hate—hate for Alan, the man
he feared might supplant him.
It seemed as if death, although burned and purified, had brought
into Keemar unrest and sin. The prayers of the High Priest himself
were unable to wash it away, until scourged and purified the earth
folk themselves became less material and more godlike and true.
The day for the Sacrament of Schlerik-itata arrived at last and the
strangers found themselves on the way to Ak-Marn’s palace.
Although the Aks had no administrative powers, as had the Jkaks,
they were held in the highest esteem, for they were princes of royal
blood.
Ak-Marn greeted them warmly. They saw that his dress was
different from the usual male costume. He was in unrelieved white,
and wore neither jewel nor ornament. The material of his robe,
which hung with a long cloak to the ground, was almost like plush
and there was something almost bridal about the costume. Yet Ak-
Marn was an old man, with a beard of white, and grandchildren in
plenty. Surely Schlerik-itata could not be the same as matrimony,
thought Mavis.
The guests were eight thousand in number, and all wore their
brightest jewels and their finest raiment.
59. There was singing and dancing and much gay chatter, and the
whole scene was one of wonderful gaiety and joy. Refreshments were
brought in, and Ak-Marn began to speak. The English people could
now understand the Keemarnian language fairly well. It was easy, its
grammar simple, and its pronunciation almost Latin.
“Friends,” said Ak-Marn. “I break bread with you. Two and ten
Kymos have sunk since I quenched my thirst or satisfied my hunger.
I’ve prayed to Mitzor, the Great White Glory and Tower of Help, to
prepare me for my journey. My call came eighty and five Kymos since
—I saw the figures in fire. I heard my call, and am prepared. I go with
hope in my heart—with joy in my breast. I am to be envied, my
friends, for my days have been long upon Keemar. I leave my loved
one, Viok, and our children, and our children’s children in your care,
my friends. When I am gone, cheer her with loving words—help her
with kind counsel. I leave you with love in my heart. I leave you with
the knowledge that our parting is not for long. Soon you will join me
in the home of the Tower of Help. Remember that the eternities of
time cannot be measured.”
Then bread was broken, and there followed the “Feast of the
Sacrament,” and the most intimate friends of Ak-Marn drank to his
“future”—drank to his coming “joy.” And Alan and Sir John were no
longer mystified. They realized that what they in their materialism
knew as “Death” was nigh—but not Death, the slayer of happiness,
Death, the dread reaper, but Death in a kindly form, a death that
gave life—a death that was glorious.
“I thought at first that the Jovians were of a finer nature than
ours,” said Alan.
“If they have conquered Death, they must indeed be high,” said Sir
John thoughtfully.
“Who is Mitzor?” asked Mavis.
“The God of our Fathers, my dear. The God of Abraham and the
God of the New Testament. Whatever their religion and ritual is, they
worship the same God as we do,” said Alan.
“Are you sure?”
“Quite.”
When the feast was ended, the guests, one by one, bade farewell to
their host. It was a long tedious business, as no one was permitted to
60. pass without at least a few personal words from Ak-Marn who was
seated on a raised chair near the doorway. And as each woman
passed out, she was crowned with a wreath of beautiful, freshly cut
flowers, from which hung a filmy white veil, while the men were
given long white cloaks with hoods which they drew over their bare
heads. Mavis bent her knee, and held out her hands to the kindly old
man. “My child,” said he. “Our beautiful ceremony is so far
meaningless to you. Go home—pray to Mitzor the Mighty that He
may refine and cleanse you, that when your time comes you may be
reincarnated to Him, through the medium of his Sacrament.
Farewell.”
To Alan he spoke long and quietly. “My son,” said he, “you are in a
strange world, you are young, you are carnal. Ah,” as Alan would
have protested, “we of Keemar, my Alan, are not as of your world. We
know not sin as you know it. Our first parents, Menlin and Jorlar,
were placed in a garden—” Alan started—“Yes, my friend, as your
parents were. They succumbed not to temptation—so they lived in
happy solitude for many years. Then Mitzor in His great kindness
gave them the knowledge of Love—Love without sin. They mated.
Their love grew. Children of love were born sinless into our world.
Child bearing was a glory; motherhood the highest estate. They knew
neither sin nor sorrow, and so in love our populace grew.”
“Do you mean to say you are sinless here?” asked Alan
incredulously.
“My son, it is not an estate for us to glory in, for the merits do not
belong to us, but to our first parents. No—real sin has never entered
here, but we live in dread of its coming. In a far off country—in
Fyjipo—there is built a large palace behind high walls. If anger, or
lust, or impatience is shown by any one of us, an order is given and
the offender is taken to the Hall of Sorrows to purge away his sins.
Should a madness come upon us, for such we reckon these failings to
be—we are kept safe until it has passed, and until we can no longer
contaminate our fellow creatures.”
“It’s a wonderful country,” said Alan. “Where we come from, is all
sin and misery and—”
“Nay, tell me not. I go on a journey. I shall face my Mitzor. I charge
you, should you or your friends feel this madness coming on you,
hide yourselves, I beg, in the Hall of Sorrows. Stay there until it has
61. passed, and preserve the purity and happiness of this land.
Farewell.” The cloak was fastened round Alan’s shoulders, and he too
left the kindly presence.
Waz-Y-Kjesta was waiting for them at the outer hall. “Go home,”
he whispered. “Your bhor awaits you. I beg of you, eat no more this
night, but in the early dawn, while Kymo still sleeps, put on your
cloaks, and the Lady Mavis her veil, and go you to the Temple of
Mitzor. Farewell.” It was a very solemn party that retired to their
rooms that night, yet the full mystery of the Sacrament had not been
unfolded to them.
It was dark when they arose, and in a dim twilight they drove to
the Temple. They had never before been inside it, and it was with
much trepidation that they waited on the threshold. It was a very
beautiful building of pale blue marble—the colour of the sky. An
enormous dome rose up in the centre of the square body of the
Temple, and at the four corners, minarets with gilded tops finished
the picture. A flight of fifty steps led up to the doors which were of a
burnished metal, and studded with precious gems. Just inside was an
antechamber, where the guests waited in silence until they were
ushered to the seats that were allotted to them. The inside was
wonderful. Mosaic walls representing allegorical tales gleamed in the
dim light; the roof was of gold, and marble pillars supported it down
the long aisle. An enormous altar rose up at the further end upon
which were carved in marble cherubim and seraphim. In the
sanctuary, if such it could be called, was a small white throne of
marble, with heavy, white curtains draped at either side. It was
placed in such a position that although it did not intercept the view
of the altar, which was high above the nave, yet it could be seen by
every one in the building.
The seats allotted to Alan and his party were very near the front
where rails of gold separated the Sanctuary from the people’s part of
the Temple. Music floated on the air—soft like babbling brooks and
the song of birds; now bursting out into thunderous praise and
mighty worship.
Suddenly there came a solemn hush; a bell tinkled; the organ
played softly, and there came the sound of boys’ sweet voices raised
in ecstasy: from a door at the side of the choir a dozen acolytes
walked dressed in their garments of white. The procession started
62. down the nave. After these boys came priests and deacons, and then
Misrath, the High Priest walked in front of a raised throne. On this
sat Ak-Marn, his eyes closed and his hands clasped in prayer. Behind
him walked his wife and their children. Their faces were radiant, it is
true; yet there was a touch of sadness in his wife’s gait. Then followed
more priests and acolytes, all singing hymns of joy.
The procession wound round the Temple, and back through the
middle aisle, and through the rails into the Sanctuary. Ak-Marn was
led to the marble throne; his wife alone of his family had followed
close behind, and now his arms were around her. Their lips met in
one long kiss, then with a bowed head she left his side, and took her
place with her family in the very front seats.
The organ thundered. Voices rang in a mighty pæan of praise.
Then silence! Misrath came forward and offered prayers to Mitzor—
prayers of offering, prayers of supplication. A mighty wreath of
freshly cut flowers was placed upon the altar. It was to be a burnt
offering, and as the smoke of the sacrifice arose on the air, the white
curtains were drawn around the figure of Ak-Marn and he was
hidden from view. Then singing rent the air; the acolytes incensed
the throne, until it was entirely covered by the perfumed smoke,
covered like a pall.
Alan watched in wonder. The grandeur of the prayers, the singing,
the mystic curtains drawn around Ak-Marn appalled him. Misrath’s
voice rose above the music.
“Children of Keemar,” he intoned. “One more brother has been
caught by the mantle of Mitzor, and has left this world for ever. He
has gone to Glory, gone to Happiness—gone to Mitzor Himself. Peace
be unto his house. Peace be unto his wife. Peace be unto his seed for
ever. We bid him—farewell.”
There was a great silence. The censers were stilled. Gradually the
smoke of the incense cleared away from the marble throne, now
gleaming in the rising rays of the Kymo.
Misrath touched the cords of the enveloping curtain, and drew
them back. The little white throne was empty! Ak-Marn had returned
to the bosom of his Creator! But stay! On the floor, as if shed in the
hurried flight of its owner, lay the bridal robe of Ak-Marn. The High
Priest raised it, blessed it, sprinkled it with the waters of purity, and
63. Ak-Marn’s wife received it in her arms. Then the mighty
congregation rose and sang one last song of praise, and at the end,
quietly left the building. And the last view Alan had of Ak-Marn’s
wife was of a solitary figure, dressed like a bride, clasping the little
white throne that was the last resting place of her loved one.
“I don’t understand,” whispered Mavis hoarsely, as they were
being driven back to their home.
“My dear, he is dead,” said Sir John.
“Dead? If that is Death, then it is something to welcome and not to
dread,” she answered softly. There was a faraway look in her eyes.
“What a wonderful Sacrament! Death that is no sorrow—only a
parting for a little while, and then—reunion.” She clasped her
husband’s hand. “Belovèd,” she murmured, “if Death comes to us
like that, then can we have no real sorrow any more. Its shadow
cannot cause us pain or grief. What do you think, Alan?”
But Alan did not answer. He was thinking of two deep blue eyes, a
laughing mouth, wilful golden curls that flirted on two soft, pink
cheeks. He was longing to crush the lithe and sweet body close to his,
and smother her roses with kisses. The knowledge and fear of Death
had lapsed; Jupiter had eradicated it,—but with its extinction had
come love. Love, stronger a thousandfold than Death. He looked
upward to where the Sun, Kymo in all his glory, was shining. The
whole world was bathed in a glory of light. Yes, Jupiter had
conquered death, and before him lay life and love!
64. CHAPTER VII
HATRED ON KEEMAR
Marlinok, the Jkak’s majordomo, called on Sir John and Alan a
few days after they had witnessed the Sacrament of Schlerik-itata.
“Will you be ready,” he asked them, “when the Kymo is at the full, to
start on your journey to Hoormoori to render homage to the Rorka?”
“Are we all to go?” asked Alan.
“But one of you need go,” he answered. “The Rorka will visit
Minniviar later, and then the other strangers may make their bows.”
“I am glad of that,” said Sir John, “for I should like to stay here in
quietness and retirement for a little while. I am beginning to feel the
burden of my age, and am worn out with the strain of the last few
years.”
“I will go to Hoormoori,” announced Alan, “I can start at whatever
time the Jkak thinks best.”
“He has prepared incense and jewels for you to take as gifts from
the absent ones,” said Marlinok, “if you will now see Waz-Y-Kjesta all
your arrangements can be made.”
“I’ll go now,” said Alan.
Alan was going down a pretty lane toward where the air birds were
housed when he suddenly became aware of footsteps behind him. He
turned—immediately the footsteps ceased, and he could see no one.
Thinking he must be mistaken, and fearing nothing from the
Keemarnians, he went on his way blithely. The air was deliciously
warm, and the fresh breeze, balmy with the scent of flowers,
tempered it. Still the footsteps followed with monotonous regularity;
as he hastened, so they became quicker; as his died down, so they
ceased altogether. Yet he had no sense of fear, no feeling of
impending evil; the thought of peril on Keemar was impossible to
imagine. The Keemarnians were of a breed as different from the
65. earth to which he belonged, as he was from Heaven! He passed
delightful homely fields, gleaming with buttercups and daisies.
Friendly cows chewed the cud in sleepy enjoyment. They did not rise
as he drew near, but only raised their sleepy heads, and looked at
him out of their liquid eyes with interest and friendliness. A pig
grunted in a corner as she suckled her squealing young; a donkey
brayed; a couple of goats were nibbling the grass while their kids
frolicked near them. He saw strange animals too. There was the
gorwa of the deer family, a beautiful creature, the colour of a Scottish
stag, and its counterpart in miniature, but with none of its brother’s
timidity. All the animals on Keemar were of a smaller build than
those he had been accustomed to. The cows were even smaller then
the little fawn Jerseys so valued in England. He had seen terriers and
bull dogs, dalmatians and spaniels in this strange world, and the
bigger breeds were all represented on a smaller scale. The Jkak had a
dog—a Borzoi, Alan would have called it, yet perhaps it was no bigger
than a small Irish terrier; but strangely enough, its beauty was not
diminished by its minuteness. So Alan went on. The way was strange
to him, but he was enjoying the calmness of the scene, and he knew
his excellent bump of locality would sooner or later lead him to Y-
Kjesta. Again the footsteps beat time with his own, and anxious for
companionship, he stepped into the shadow of a tree, and hoped to
waylay a shy, but friendly stranger. A second passed. The footsteps
had ceased—then came a rustling, and the head of Kulmervan the
Student appeared over a honeysuckle bush. Silently he came
forward, alert and watchful until he was on a level with Alan.
“Hullo!” said Alan amiably. “Where are you going, Kulmervan?”
The effect was magical! Kulmervan jumped as though he had been
struck, and his face whitened. He remained silent. “I’m going to see
Waz-Y-Kjesta,” went on Alan. “Are you coming my way?”
Kulmervan did not reply, but a baleful light gleamed in his eyes,
and his mouth twitched.
“What’s the matter?” asked Alan curiously.
Suddenly Kulmervan spoke, and there was a wealth of passion in
his tones. “Why did you come here, you strangers? I was happy until
you came. I was contented. You have made me want—want the
unknown. You have stirred my heart and filled it with longings that I
66. cannot yet fathom. Why have you come to stir up misery among a
happy and contented race?”
“I don’t know what you mean,” said Alan, “I have done nothing.”
“You’ve done everything. You dared to raise your eyes to the level
of Chlorie, our Ipso-Rorka. You put thoughts about her into my head.
Oh—” as Alan would have broken in—“I read your thoughts, it was
easy, my friend. You dared to think of her as a woman—even your
woman. It was an impertinence, I tell you. I love Chlorie with my
whole soul, and before Mitzor the Mighty, I’ll carry her away into
some far off land, before she can look with a favourable eye on a
man, not only of another world, but a man of a coarser nature than
our own.”
Kulmervan was breathless when he finished, for his words had
come thick and fast, tumbling over themselves in his great
excitement. Alan was speechless, and looked as he felt, absolutely
uncomfortable and ill at ease. “Why your very pose proves guilt,”
continued Kulmervan.
“Why should I not love Chlorie?” demanded Alan, “Why should my
love for her cause strife between us?”
“Because, my stranger, I am a Prince of the Rorka’s House. I am
not only Kulmervan the Student; but Taz-Ak of the House of Pluthoz.
Why else would Chlorie have honoured my party—why else come to
the dance of a student? There are but four Keemarnians that Chlorie
can marry, and I rank second.”
Alan wondered at the time why the Princess should come in so
natural a manner to the Student’s reception. He wondered at the
time at her familiarity with Kulmervan. She had patted his hand,
smiled into his eyes, and had honoured him more than once with a
dance.
But Alan, too, was in love. Idiotically, insanely in love with a
woman who had not even troubled to raise her eyes to his, at his
presentation. His pulses throbbed at the remembrance of the touch
of her fingertips as he raised them to his lips. He loved her, and in
that moment was born a desire to overcome all obstacles, and
princess or no princess, to win her. But he knew too that in this
pleasant land of Keemar an enmity had come upon him, and
wondered whether the Curse of Death had brought it. He wondered
67. whether the dead and decomposed body of their faithful Murdoch
had indeed brought sorrow to this fair land.
“I’ve spoken to your Ipso-Rorka only once,” said he. “The night of
your party. She has called on my uncle and Mavis. Mavis has been
out driving with her several times. But I, unfortunately, have missed
her each time. Surely you are not jealous because I—”
“Because you love her? I am,” said Kulmervan thickly, “and I say
this—if you so much as dare to raise your eyes to her, if you dare to
address her, I’ll make you suffer for it—aye, even though I also suffer
eternally for it,” and with that he turned on his heel and walked
quickly away.
Alan was very perturbed about this meeting, and felt inclined to
tell the story of it to Waz-Y-Kjesta,—yet the sacred feeling he had for
Chlorie was not to be spoken of, or bandied about from man to man.
No, he would keep it to himself, and trust to time and common sense
to cure Kulmervan of his strange hatred.
He walked quickly on, and already could see the air birds in the
distance, circling above their houses. The little lane turned quickly at
right angles—there was a steep descent, and hedges rose at either
side to a height of six or seven feet, while the overhanging branches
of the trees met in the middle and formed a leafy arch. The grassy
banks were carpeted with flowers, and the scent hung sweet on the
air. Again the narrow path turned sharply to the right, and before
Alan realized it, there almost at his feet, stretched across almost the
full width of the path, lay a lion, full grown, with his shaggy mane
stirring in the breeze. Alan stopped suddenly, and his heart beat
quickly. The lion’s eyes were closed—he was sleeping.
The Englishman was almost afraid to move lest the savage beast
should spring upon him and devour him. He looked round to the
right, the bough of a tree hung low over the path. He leapt up the
bank, and with one mighty spring caught hold of it, and swarmed up
to a topmost branch.
He was safe—but the sudden sound had startled the lion, who rose
up and with a low growl prowled backward and forward beneath the
tree.
It was an uncomfortable position to be in—the tree bough was very
thin, and bent and twisted and crackled ominously. Still the King of
68. Beasts remained sentinel underneath. Alan felt the perspiration on
his face as the limb shivered and bent, yet there was no other to
which he could move. Still the animal remained near, his quickened
senses no doubt wondering at the noise he heard, and waiting to see
what had caused it.
The minutes dragged by—the branch was weakening perceptibly—
he could already see the white of the inside where the branch was
gradually tearing away from the parent trunk. There was no one in
sight, and still the lion walked restlessly to and fro.
The Kymo was sinking rapidly. It was already low down on the
horizon, and Alan knew he had been about two English hours in his
perilous position. He saw a branch above his head, and he wormed
his way along to see if he could in any way reach it. Carefully he went
—slowly—suddenly with a scream and a crash the branch gave way,
and Alan felt himself being hurled to the ground.
The distance was not great, and he landed in the centre of some
sweet-smelling, soft bushes. He was dazed, and wondered when the
lion would pounce. He knew he was powerless to help himself. He
heard the pad, pad, of its feet; he could hear the sharp intake of its
breath—then the thing was upon him. He shut his eyes and waited.—
Nothing happened but the snuffing of the wild beast, and a gentle
nosing as it examined the stranger.
Alan opened his eyes. The animal was sitting on its haunches
surveying him, and he felt there was amusement in the beast’s eyes
as it watched him. He moved slightly—still the beast watched
motionless. He raised himself up from the encircling bushes and
clambered down. He knew he would have to face the inevitable.
Suddenly a voice hailed him, and he saw Waz-Y-Kjesta coming
round the bend in the lane. “Stand back,” he cried. “There’s a lion
here—he may spring!” But the Waz came on fearlessly. Alan was
petrified, his tongue was parched, no sound came from his lips. He
watched the Waz in frozen horror.
The Keemarnian was smiling. “Where have you been, my friend?
You are late—very late. I thought you had missed your way, so I came
to seek you.” He was now within three feet of the lion. “What is the
matter? Why are you so grave? Has aught affrighted you?”
69. Alan pointed to the tawny beast. His hand was shaking. Surely the
farce must end soon, the lion spring, and tragedy culminate the play.
“Why Maquer,” said the Waz affectionately, “what are you doing
here? You seldom visit us, you know.”
The lion moved toward him, and rubbed his great head against the
Keemarnian’s leg, while Y-Kjesta talked to him and petted him.
“He’s tame then?” gasped Alan with a rush of relief. “You know
him?”
“No, my friend. I’ve never seen this Maquer before—they generally
stay in rocky places.”
“But he is so friendly.”
“All beasts are friendly here, my Alan. What—would Maquer have
hurt you on your Earth?”
And Alan laughingly told of his fright at the lion. He had learnt one
more truth about Keemar—there were no savage animals upon it. Of
a truth, it was a perfect land!
Waz-Y-Kjesta was highly amused at his friend’s story, and together
they went toward the air birds. The Keemarnian airships were indeed
wonderful creations. White and gold, they were shaped like swans,
with graceful wings outspread, gleaming in the light. They were
made of a mixture of wood and metal, and contained
accommodation for perhaps forty passengers, as well as the Waz in
command, and a staff of ten. Although not as big as the ill-fated
Argenta, the Keemarnian airship was possessed of a speed nearly
thrice as great.
“This is the Chlorie,” said Y-Kjesta, “and our fastest bird. The Jkak
has given orders that you are to choose your own vessel, so perhaps
you would like to see over some others?”
“No,” said Alan, looking at the blue hangings, and seeing in them
the reflection of his love’s eyes. “No, this one will do beautifully.” And
the Waz was impressed by the easy way in which his friend was
pleased. He little realized that it was the name of the vessel—the
Chlorie—that attracted him. And in the strangeness of it Alan tried to
read his fate.
“We’ll go for a short cruise,” said the Waz, “and go back to the
landing stage Minniviar.”
70. There was not a cloud in the sky, and the warmth from the sun’s
rays was pleasant.
“I can’t understand how you benefit so considerably from the sun,
your Kymo,” said Alan. “Let me see, you must be at least five times
further away from the sun than we were on our earth, yet instead of
your light and heat being reduced to about one twenty-fifth of our
supply, you appear to benefit to exactly the same degree.”
“Ah, my friend, that is easy to explain. Dark clouds hover outside
our globe—”
“Yes, bands of vapour,” corrected Alan.
“Well—vapour. These bands completely encircle our world. They
are saturated with a composition of gas, sulphuric ether I think you
would call it. Well, this gas acts as a trap to the sun’s rays. It admits
the solar rays to our planet but prevents their withdrawal. Therefore
it permits the heat to enter, but prevents its escape.”
“Well?”
“Consequently we get the maximum of light, and an equable
temperature.”
“Do you then, have no seasons here?”
“Seasons?”
“Yes, Spring or Winter.”
“Oh yes, it is cold at the poles—very cold, but as we get nearer to
the equator it becomes warmer, and hardly varies. You see, my Alan,
our world differs from yours. The axis of rotation is almost
perpendicular to our orbit, consequently we are not subject to
seasons as you were in Quilphis.”
“I didn’t know that before.”
“We too, are more flattened at each end—indeed, there are many
differences between our world that is, and yours that was.”
“Do you ever have rain here?”
“Yes, my Alan. How else would plants live and crops thrive? But
again, we do not suffer from excesses.”
“But don’t you have hurricanes that last from six to seven weeks?
Surely those are excesses.”
“Hurricanes? I do not know the word.”
71. Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!
ebookgate.com