Arrow of time
Arrow of time
Installing Django on Windows

Though it is obviously a blasphemy, sometimes it is actually necessary to run Django on Windows - mostly due to a …

Though it is obviously a blasphemy, sometimes it is actually necessary to run Django on Windows - mostly due to a client having based its infrastructure around the Windows ecosystem. The "blasphemy" part comes from Django being a really nice framework which evolved on and for a Unix-like system, and it relies heavily on features like WSGI, FastCGI, and command-line tooling which are foreign to the Windows environment. Luckily, the compatibility is improving, by features being added both to the Windows side and to the Python+Django side - features which would otherwise be a kludge but which solve crucial compatibility problems.

This short tutorial will demonstrate the the basic set-up of a Django project on Windows. It will cover the installation of Python, Django, and related tools, and running the Django project both standalone and as a FastCGI server. The latter part is especially important since the IIS officially supports FastCGI as of lately (on IIS 7+, simply install the CGI feature). The tutorial will cover Python 2.7 and Django 1.7 as I use those versions for my projects.

The tutorial is intended for people which have working understanding of Windows and are familiar with the IIS server.

Pro tip: If you are going to deploy multiple Django (or even plain Python) projects, or if you are a developer, you should look at virtualenv.

Installing Python on Windows

First, download Python. Both 32-bit and 64-bit MSI installers are provided, and you should choose one accordingly. It is especially important that you install Python 2.7.9 or a later version, since they come with PIP, the Python library / package / software manager which is used to install everything else.

The installer process is very straightforward and simple. It will offer to install Python in the C:\Python27 directory, which you should accept as it makes life easier afterwards. Try not to give in to the Windows habit of installing stuff in directories with spaces in their names.

The basic directory after installation will contain around 8 subdirectories, some miscellaneous files and two executables named Python.exe and PythonW.exe. The former is the default command-line interpreter and Python shell, while the latter is only the interpreter, which will not use (or spawn) a console window if invoked (and because of that is suitable for running GUI Python applications).

Next, Python should be added to the system's PATH environment variable. This is done in Advanced System Settings (or System Properties), in the Advanced tab, by clicking on the Environment Variables button. There are two directories to be added: C:\Python27 and C:\Python27\Scripts. These should be appended to the PATH list, separated by semicolons (;). The ending of your PATH variable should look like ;C:\Python27;C:\Python27\Scripts.

Pro tip: You may also want to install GOW, a light-weight collection of Unix command-line utilities similar to Cygwin. It will provide you with tools such as ls, but also more interesting ones such as make, wget, curl, ssh, scp, gzip and tar.

The basics of PIP

PIP is the tool which installs and maintains Python libraries (of which Django is only one example; there are thousands of useful Python libraries). It is invoked by running the pip command on the command prompt, and has several sub-commands, among which the two most useful ones are install and freeze.

Running pip install <package_name> will download and install the package and all of its dependencies (which may be nested and fairly complex). Running pip install --upgrade <package_name> will likewise upgrade an existing package to its most recent version. PIP supports a special syntax for installing precise versions of a package instead of the "most recent one". It is done by appending an operator and a version number to the package name, e.g. "Jinja2==2.7.3" or "six>=1.8". The first one will install a precise version of a package, and the second one will install any version equal to or larger than the given version number.

Running pip freeze will simply show the list of currently installed packages, in a format which is directly usable to pip install.

Note that some Python / PIP packages come with a library written in C, which must be compiled for the package to work. Unless you set up your system to have a working C compiler which is also compatible with the Python executables, you will not be able to install those. Django is a pure Python library so it does not require a C compiler to install.

Installing Django

Django can be installed using PIP with a command such as pip install django. The process may pull in some additional dependencies if they are not already present on your system. Otherwise, it will simply install only Django, with an output similar to the following:

Downloading/unpacking django
Installing collected packages: django
Successfully installed django
Cleaning up...

You can check if both Python and Django are working by starting a new Windows Command Prompt, running the python command, and writing the import django command in the Python prompt:

Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>>

If everything goes ok, no output should be visible.

PIP is also the way project dependencies (additional libraries) are installed, should the project have them.

Installing a Django project

A Django "project" consists of one or more "apps". A project's top-level directory usually contains one special project subdirectory which contains settings and some general project-level information, one subdirectory per app, and a command-line script called "manage.py". An example directory listing is:

C:\Devel\djangoproject\src>dir
 Volume in drive C is OS
 Volume Serial Number is 6A3D-C1B8

 Directory of C:\Devel\djangoproject\src

22/12/2014  04:25    <DIR>          .
22/12/2014  04:25    <DIR>          ..
22/12/2014  04:19    <DIR>          project
22/12/2014  04:58    <DIR>          djangoapp
16/12/2014  03:30    <DIR>          templates
16/12/2014  00:50               250 manage.py
                           1 File(s)            250 bytes
                           5 Dir(s)  23,552,929,792 bytes free

Django projects can be simply distributed by archiving the entire project directory and decompressing it on another machine. In the example above, the project contains the "project" subdirectory, the application directory named "djangoapp", and an auxiliarry "templates" subdirectory.

The manage.py script is the "swiss army knife" of Django applications - it does everything from creating new apps, to database migrations, to running a test (embedded) HTTP server or a FastCGI server.

Running a test HTTP server

If the project and its apps are functional, you should be able to start the default Django development-only HTTP server by running the command manage.py runserver, which will result in an output similar to the following:

C:\Devel\djangoproject\src>manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
December 23, 2014 - 01:19:02
Django version 1.7.1, using settings 'project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

As you can see from the messages, it will start a server on localhost, port 8000. You can access it immediately with your web browser.

Configuring and running a FastCGI server

A more interesting option is enabling a FastCGI server. With FastCGI, you can use IIS, Apache or any other web server to serve the application in a production setting. For this to work you need to download the fcgi.py file (also available at its original location and put it into the management/commands subdirectory of the Django app's (not the project's!) subdirectory. Both the "management" and the "commands" subdirectory must have an empty file named __init__.py (which make those directories Python modules).

The fcgi.py described previously is a very simple and minimalistic WSGI to FastCGI adaptor which does not support listening on a TCP socket or a pipe, and does all its processing by using stdin and stdout. As such it is not usable with modern web servers such as nginx, but will work with IIS.

Configuring IIS to run a FastCGI application

If the FastCGI module is loaded in IIS (or simple the CGI module in IIS 7+), the IIS management console will have the "FastCGI Settings" icon available. Django is a framework which has its own URL routing, so django apps must be installed as a "handler" in IIS for specific paths. To install a Django app on the IIS's Default Web Site, select it in the management console, and open the Handler mappings configuration feature. In it, click on the Add Module Mapping... action, and enter the following information:

  • Request path: set it to '*' to handle all requests with internal Django routing
  • Module: set it to 'FastCgiModule' to use the IIS's FastCGI module
  • Executable: here both the python.exe path and its command line arguments need to be set, using the pipe character (|) as a separator. An example value for this setting is: C:\Python27\python.exe|C:\Devel\simplebom\src\manage.py fcgi --pythonpath C:\Devel\simplebom\src --settings project.settings. Note that you need to specify the fcgi command for the manage.py script, and manually set the Python interpreter's search path for the project, as well as the Pythonic module name for the project's setting module.
  • Name: set it to whatever you like

Your configuration dialog should look something like this:

A Django app handler configuration for the IIS

Next, click the Request restrictions button and edit the Mapping tab. You need to turn off the "Invoke handler only if the request is mapped to..." checkbox, or otherwise IIS will have problems mapping what it thinks are subdirectories in the URL request:

Turning off request restrictions for mappings

After clicking OK on the handler information dialog, IIS will ask you to confirm the creation of a matching FastCGI application entry, and you must allow it to make one. This entry will be visible in the FastCGI Settings feature, accessible at the root screen of the IIS Management Console. The default entry created by IIS itself is good enough to work with, but there are some optional settings available which can be very convenient:

  • Max instances: This particular way of running FastCGI applications is single-process, single-threaded, meaning a separate Python interpreter process will be started for each simultaneous request. This setting limits the number of simultaneous Django app instances.
  • Monitor changes to file: By default, once started, the app processes will be active either until manually shut down, or until they handle Instance MaxRequest requests. By using this setting, IIS will monitor a timestamp of an arbitrary file, and if it changes, it will stop and reload app instances. This is convenient both for developers and for production environments, as it allows apps to be reloaded when changed. The "monitor a file's timestamp for a reload indicator" is a fairly strange concept on Windows, but it's normal in Unix-like environments, and so it was carried here with FastCGI.
Configuring a FastCGI app

Configuring the static resource and media directories

Modern web applications use multiple resource files, such as CSS, JavaScript and others, and Django apps are no exceptions. Django provides for a very convenient feature which allows the developers to integrate the needed resources into the application directory tree, but which can be extracted and copied by Django into a proper, static directory. This is basically a developer-controlled feature, and the locations where Django will store the static files is controlled in the project's settings.py. Well-behaved projects will use a reasonably sane path for this, but it is not standardised.

Apps which handle uploaded files store them in a similarly managed directory which in Django is traditionally named media. To handle the static and media directories, they need to be added to the IIS configuration as virtual directories:

Configuring an IIS virtual directory

The important step here is to reconfigure the Handler Mappings feature for each of the directories and remove the Django App handler, leaving the "StaticFile" handler as the most important one.

Note that the static directory must be readable by the IIS (as well as all other files and directories in the Django project), but the media directory must also be writeable by the IIS. The final site configuration should resemble the following screenshot:

IIS configured with Django :width: 500

A note on databases

SQLite works by default, on Windows as on Unix-like systems. Most of the other open source databases now work on Windows, even PostgreSQL, which I recommend. On existing Windows installations, though, there could be a requirement to deploy Django with the MS SQL Server. This is possible either by using an ODBC bridge driver or by using a native MS SQL driver. In theory, both work but I haven't tested them. At least the database connection parameters (in the project's settings.py file) need to be changed to switch to a new database. Data migration needs to be done manually.

Note that if using the SQLite database, both the database file and the directory where it is located need to be writeable by the IIS.

Troubleshooting

The described configuration is tested and proven to work, but if something goes wrong, here are the steps for basic troubleshooting:

  1. Try starting the FastCGI command line yourself. This is the command configured in the FastCGI Settings and which must match the one configured in Handler Mappings for the site.
  2. Install the Tracing feature for the IIS, then configure it for the Django site in Failed Request Tracing Rules to trace all content (*), the status code "500" and the event severity "Error". The traces will be available as XML files (with attached XSLT) in the IIS's C:\inetpub\logs\FailedReqLogFiles directory (or a similar one, depending on your configuration). You then need to enable tracing for the particular web site (or a virtual directory) in the Configure->Failed request tracing... action.

Online.net physical ARM-powered cloud

Online.net is a French hosting company offering the usual range of services from simple web hosting for 1 € / mo …

Online.net is a French hosting company offering the usual range of services from simple web hosting for 1 € / mo to dedicated servers, but with a twist I haven't seen before: their offer of dedicated servers is incredibly affordable! See this example: for 6 € / mo you can get yourself a dedicated VIA Nano x86 CPU powered server completely for your own usage. These CPU's performance is comparable Read More


Intel Atom vs Xeon performance

I recently got myself a small laptop, an Asus Transformer Book T100TA, and I'm surprisingly happy with it. The current …

I recently got myself a small laptop, an Asus Transformer Book T100TA, and I'm surprisingly happy with it. The current generation of these devices is what netbooks were supposed to be: very portable, with a very long battery life, but still powerful enough to be usable. In fact, I'm writing this blog post on it. Finally, both the hardware and the software (the device is running Windows 8.1 and I'd be crazy...

Read More
On (artificial) intelligence

Consider this armchair philosophising on the possibility of artificial intelligences. My stance on the existence of our biological intelligence is …

Consider this armchair philosophising on the possibility of artificial intelligences. My stance on the existence of our biological intelligence is that it's a matter of accident, in the sense that all evolved traits are basically accidents: random mutations which get selected for over a large time span. It was very probably honed during that time, as individuals which had "more of it" had an advantage over the others. However, something singular must have happened some time ago, some...

Read More
Story: The Sin

It looks like "the writing bug" comes with the territory of being a nerd with an abundance of ideas and …

It looks like "the writing bug" comes with the territory of being a nerd with an abundance of ideas and a complete lack of time to do them in. I have been writing mostly technical articles for almost 10 years now. In this time I've written literally hundreds of articles, at a rate of approximately one every week or so, most of them for a real, printed IT magazine in Croatia named Mreža. That's all in...

Read More
Why I listen to Nick Cave

Just listen to this as the sountrack to this post. I hope it will not be a long one. A …

Just listen to this as the sountrack to this post. I hope it will not be a long one. A few days ago I was surprised, and a bit amused when some of my friends told me they think I'm a pretty cheerful and relaxed person. Which got me thinking of the ways in which they were right and where they were not. Soon after that event I've watched Nick Cave's...

Read More
We should replace asm.js with Rust

I can't be the only one to think there is something horrible about today's JavaScript. It is like a Lovecraftian …

I can't be the only one to think there is something horrible about today's JavaScript. It is like a Lovecraftian programming language from outer space - it is here to stay, and if you follow certain forums it looks like it's spread absolutely everywhere and absorbed every other language, but at the same time it just seems so damned indescribably icky. It was a toy language that went nuclear. With just...

Read More
The Needle Search Server - alpha

I've written before about my Needle light-weight full-text search server. To recap: it's a full-text search server written in C …

I've written before about my Needle light-weight full-text search server. To recap: it's a full-text search server written in C++ with a FastCGI interface, using Google's LevelDB for storage, and with a pure REST API. It's available at BitBucket if you want to test it yourself! As these things go, it took me a lot more effort to find the time to work on Needle, but I'm managing it here and there....

Read More
What Django caching can do

Nothing special here, just wanted to make a note about how simply turning on Django caching can bring a site's …

Nothing special here, just wanted to make a note about how simply turning on Django caching can bring a site's performance up from this: Server Software: nginx/1.2.1 Server Hostname: vo.ivoras.net Server Port: 80 Document Path: /api/location/1 Document Length:...

Read More
My Font Awesome to bitmap converter

A few months ago I created a small script which extracts Font Awesome glyphs and creates transparent PNG images, with …

A few months ago I created a small script which extracts Font Awesome glyphs and creates transparent PNG images, with some fancy additional options such as shadow / emboss. My friend Saša then prettied it up a bit and we basically forgot about it - I didn't even describe it on this blog :) I've just needed an image from this project so I'd thought I'd finally write...

Read More
Amazon's E-book Price-slashing Campaign and on Replacing One Evil with Another

Earlier today I have received a letter from Amazon, which I'm going to copy-paste below for completness and archival. It …

Earlier today I have received a letter from Amazon, which I'm going to copy-paste below for completness and archival. It basically tries to invoke sympathy for Amazon in its "debate" with a publisher called Hachette. I don't follow the publishing world that closely and I admit to never hearing about Hachette until earlier today, but I am very aware of the problem at hand, which is pricing and distribution of digital goods...

Read More
How do you explain an OS kernel to a layperson? + an old text about The Matrix as an Operating System

Earlier this year I was a guest at a gathering of people who were mostly involved with social sciences and …

Earlier this year I was a guest at a gathering of people who were mostly involved with social sciences and politics and a topic soon arised in which I had to explain some of the things I work with. In this group of 10-ish people there were one or two who had even a vague idea what a kernel is (they were engineering students, actually), and were suitably impressed, but the rest of the group simply offered...

Read More
On constants in algorithmic complexity, and comparing apples to oranges

Can an O(n!) algorithm be faster than an O(1) algorithm? Yes, of course it can. So I came …

Can an O(n!) algorithm be faster than an O(1) algorithm? Yes, of course it can. So I came across an interestring and almost trivial programming puzzle: given an arbitrary word and a dictionary of words, find all anagrams of the word present in the dictionary. At first I didn't care to think about the best solution for the problem and I just wrote a trivial, brute force solution as a proof of concept: from itertools...

Read More
How about a Digital Price Tag?

How about adding intelligent information to our price tags? BitCoin and DogeCoin (and others) already have payment URLs, but we …

How about adding intelligent information to our price tags? BitCoin and DogeCoin (and others) already have payment URLs, but we can do better than that! The easiest way to offer something for purchase using cryptocurrency is simply to link and/or describe what you want to the buyers on your web shop. You don't really need middle-men and merchants to do so: it's easy to create your own "BUY" link yourself. Option #1: payment URL's Most people know...

Read More
Can UBI be tested with Digital Currency?

This article on the discrepancy between consumers' lifestyle and deteriorating workers' rights has sparked a prodigiously long discussion on the …

This article on the discrepancy between consumers' lifestyle and deteriorating workers' rights has sparked a prodigiously long discussion on the Futurology subreddit (where the usual median length of the discussion is somewhere around 10 comments). Such topics now regularly venture into discussing the merits of Universal basic income (UBI), which as an idea was practically non-existent in the mindset of two or so years ago. An offhand Read More


The Pirate party of Croatia - what went wrong

The context of this article is that it's a sort of a post-mortem written from my own perspective of what …

The context of this article is that it's a sort of a post-mortem written from my own perspective of what went wrong in the Pirate Party of Croatia, now that I've left it. I've been one of the founding members and after more than two years' work I must admit that the number of accumulated problems has surpassed the level at which we can be productive, and that I cannot aid in solving them. Simply put, people in general (at...

Read More
The Needle Search Server - pre-alpha

I've talked about my new project, the Needle Search Server before - it is supposed to be a light-weight full text …

I've talked about my new project, the Needle Search Server before - it is supposed to be a light-weight full text search server written in C++ and using LevelDB for storage. I've arrived at a point where the code actually does something useful and I want to talk about it some more. Of course, you will need to fetch and compile the code yourself and once you get over that hurdle, you...

Read More
A brief history of computing in error messages

Technologies and systems come and go but error messages stay. Of course, this is because errors are (or were, before …

Technologies and systems come and go but error messages stay. Of course, this is because errors are (or were, before exceptions) signified by integer error codes and libraries maintain, among other things, dictionaries of human-readable messages to go with such codes. Most system programmers, or any other programmers which still dwell on C instead of using something less close to the metal, can remember a subset of those codes simply because they've seen them often enough. I first...

Read More
Dear Google, make me a Phone

Dear Google, please make me a Phone which lasts 24h. Heck, even 18h would be a marked improvement since no …

Dear Google, please make me a Phone which lasts 24h. Heck, even 18h would be a marked improvement since no phone that I've used lasts me even 12h. You see, I actually use my devices, they are not sitting in my pocket among the lint. Also, I don't use them for playing games or mining Bitcoin, but for reading and communicating. Please, dear phone industry, get your collective heads out of your asses and make a phone which: Has a CPU...

Read More
Starting a new project - Needle

I have recently built an "Open Government" service which takes all the documents from the official Croatian government gazette which …

I have recently built an "Open Government" service which takes all the documents from the official Croatian government gazette which, among other things, publishes laws, changes to laws, decisions of the Constitutional court, etc. and indexes them, offering two new services: better full-text searchability and data "push" approach, allowing users to "subscribe" to arbitrary search queries and get notified when there are new documents published which are matched by those queries. Though these documents are pro-forma published on-line at...

Read More