When thinking about your development environment, there are three important things to keep in mind: isolation, determinism, and similarity. They’re each important, and they work in concert with one another.
Isolation means that you’re not inadvertently leveraging tools or packages installed outside the environment. This is particularly important when it comes to something like Python packages with C extensions: if you’re using something installed at the system level and don’t know it, you can find that when you go to deploy or share your code that it doesn’t operate the way you expect. A tool like virtualenv can help create that sort of environment.
Your environment is deterministic if you’re confident about what versions of your dependencies you’re relying on, and can reproduce that environment reliably.
Finally, similarity to your production or deployment environment means you’re running on the same OS, preferably the same release, and that you’re using the same tools to configure your development environment that you use to configure your deployment environment. This is by no means a requirement, but as you build bigger, more complex software, it’s helpful to be confident that any problem you see in production is reproducable in your development environment, and limit the scope of investigation to code you wrote.
You can specify versions either by the version for a package on PyPI, or a specific revision (SHA in git, revision number in Subversion, etc). This ensures that you’re getting the exact version you’re testing with.
$ mkdir tutorial $ virtualenv ./tutorial/ New python executable in ./tutorial/bin/python Installing setuptools............done. Installing pip...............done. $ source ./tutorial/bin/activate (tutorial)$
Create a requirements.txt in the tutorial directory with a single requirement in it.
And then we can use pip to install the dependencies.
(tutorial)$ pip install -U -r requirements.txt Downloading/unpacking Django==1.5.1 Downloading Django-1.5.1.tar.gz (8.0MB): 8.0MB downloaded Running setup.py egg_info for package Django warning: no previously-included files matching '__pycache__' found under directory '*' warning: no previously-included files matching '*.py[co]' found under directory '*' Installing collected packages: Django Running setup.py install for Django changing mode of build/scripts-2.7/django-admin.py from 644 to 755 warning: no previously-included files matching '__pycache__' found under directory '*' warning: no previously-included files matching '*.py[co]' found under directory '*' changing mode of /home/nathan/p/edt/bin/django-admin.py to 755 Successfully installed Django Cleaning up...
When a building is under construction, scaffolding is often used to support the structure before it’s complete. The scaffolding can be temporary, or it can serve as part of the foundation for the building, but regardless it provides some support when you’re just starting out.
Django, like many web frameworks, provides scaffolding for your development efforts. It does this by making decisions and providing a starting point for your code that lets you focus on the problem you’re trying to solve, and not how to parse an HTTP request. Django provides HTTP, as well as file system scaffolding.
The HTTP scaffolding handles things like parsing an HTTP request into a Python object and providing tools to easily create a response. The file system scaffolding is a little different: it’s a set of conventions for organizing your code. These conventions make it easier to add engineers to a project, since they (hypothetically) have some idea how the code is organized. In Django parlance, a project is the final product, and it assembles one or more applications together. Django 1.4 made a change to the way the projects and applications are laid out on disk, which makes it easier to decouple and reuse applications between projects.
Django installs a django-admin.py script for handling scaffolding tasks. We’ll use startproject to create the project files. We specify the project name and the directory to start in; we’re already in our isolated environment so we can just say .
(tutorial)$ django-admin.py startproject addressbook .
manage.py ./addressbook __init__.py settings.py urls.py wsgi.py
(tutorial)$ python ./manage.py startapp contacts
./addressbook ./contacts __init__.py models.py tests.py views.py