Project structure¶
Everybody tends to have a personal preference for the structure of their project, and I’m no different. After some trial and tweaking I’ve come up with a structure I’m quite happy with.
Setting up the project¶
First, activate the django-foobar
environment if it’s not already active. Next we need to install
Django itself into the new environment.
~$ workon django-foobar
(django-foobar):~$ pip install Django
Creating the working directory¶
(django-foobar):~$ mkdir django-foobar (django-foobar):~$ cd django-foobarNote
Whenever referring to the “working directory” in this guide, I’m referring to this. In other words, the top level directory for the entire project.
Set up the testing environment¶
TDD is a good practice to follow when writing 3rd party Django modules. If you want your library to succeed and people to use and contribute to it, you’ll need a good test suite! We are going to use the
django-admin
command to create a testing environment for our module. Inside the project directory enter the following command (make sure you include the.
on the end!)(django-foobar):~/django-foobar$ django-admin startproject tests .Now, you might be wondering why we are using the
django-admin startproject
command to create the testing environment, and not the module we are going to develop. That’s because we don’t want to distribute an entire Django project. We only want to distribute thedjango-foobar
library we’re going to write, but we want to make sure it can run in an existing Django project. That’s what we’re going to use thetests
project for!
Module source code¶
Next, we need to create a directory containing the source code for our
django-foobar
module. Python modules uses underscores instead of dashes in their package names, so the python module will be calleddjango_foobar
. Either create a directory calleddjango_foobar
with an__init__.py
file inside it, or just use thedjango-admin
command to create a new app.(django-foobar):~/django-foobar$ django-admin startapp django_foobar
Documentation¶
Obviously, we need to document our library. This can be done with various tools, but I like to use Sphinx. That’s the very same tool I’ve used to write this guide, so you know how the documentation will look like =)
(django-foobar):~/django-foobar$ pip install Sphinx ... Lots of stuff going on ... (django-foobar):~/django-foobar$ sphinx-quickstart docs Welcome to the Sphinx 1.3.1 quickstart utility. Please enter values for the following settings (just press Enter to accept a default value, if one is given in brackets). Selected root path: docs You have two options for placing the build directory for Sphinx output. Either, you use a directory "_build" within the root path, or you separate "source" and "build" directories within the root path. > Separate source and build directories (y/n) [n]:Just hit
<enter>
for default values and write some sensible values for those which requires input (like project name, author, and so on).
Requirements¶
The
requirements.txt
file contains all the libraries required for developing the module. Requirements for installing the module will be in another file calledsetup.py
. Don’t pay any attention to that for now, we’ll create it later in this guide.Create the
requirements.txt
file in your project root.(django-foobar):~/django-foobar$ touch requirements.txtOpen the file in a text editor and add a few dependencies. It’s quite common to lock dependency versions when developing a library, but it’s not strictly required. If no version lock is found,
pip
will install the most recent version.Django==1.8.4 Sphinx==1.3.1 sphinx-rtd-theme==0.1.8We’ll be adding more to this file as we go along.
README.txt and LICENSE.txt¶
Create a README.txt and LICENSE.txt file. The README.txt file should contain a brief description of the module, as well as other useful information. In case you decide to upload your project to a source hosting service such as Github or Bitbucket, the content of this file will be displayed on the front page of your repository.
The LICENSE.txt file is not so important right now, but if you are going to distribute the source code, it is good practice to slap a license on it. There are many licenses to choose from, but I tend to choose a fairly liberal license such as the MIT License or the Apache v2.0 License. There is no single license which match every project, so choosing the right one depends a lot on the project type and use case. Also, if you work for a company, they might have their own rules and restrictions for licensing source code, so make sure to pay attention to that as well ;)
You don’t have to decide now, just leave the LICENSE.txt file there as a reminder. Check out this link for a list of popular open source licenses.
(django-foobar):~/django-foobar$ touch README.txt LICENSE.txt
Source control¶
This step is optional, but you probably want to add source control to your project. There is different source control tools, but I like Git, so let’s initialize a git repository in the project root.
(django-foobar):~/django-foobar$ git init Initialized empty Git repository in /path/to/your/project/.git/Not all files in your project should go into source control. Add a
.gitignore
file in order to tell Git which files or directories to ignore.(django-foobar):~/django-foobar$ touch .gitignoreOpen the .gitignore file in your favorite text editor and paste the following lines:
__pycache__/ *.py[cod] build/ dist/ sdist/ .eggs/ *.egg-info/ # Unit test / coverage reports htmlcov/ .tox/ .coverage .cache nosetests.xml coverage.xml # Translations *.mo *.pot # Django stuff: *.log *.db # Sphinx documentation docs/_build/You can add stuff to this file as you go along in case there’s something we have missed.
Now is a good time to commit your work!
(django-foobar):~/django-foobar$ git add * (django-foobar):~/django-foobar$ git commit -m "initial commit"
Github¶
If you don’t have a Github account, go ahead and create one now!
Create an empty repository for your code
Fill in some details about your project, but make it public.
Push your code to the new Github repository.
(django-foobar):~/django-foobar$ git remote add origin https://github.com/<your-user>/django-foobar.git (django-foobar):~/django-foobar$ git push -u origin master
Enter your credentials when asked.
There. We now have a pretty good project structure for developing the amazing django-foobar
module.
It should look something like this:
├── LICENSE.txt ├── README.rst ├── django_foobar │ ├── __init__.py │ ├── admin.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── docs │ ├── Makefile │ ├── _build │ ├── _static │ ├── _templates │ ├── conf.py │ ├── index.rst │ └── make.bat ├── manage.py ├── requirements.txt ├── .gitignore └── tests ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
Write some code¶
Now, this is not a guide for writing Django code, so we’ll just write a small testable unit in our
django_foobar
module.
Open the django_foobar/views.py
file in the and write in the following code.
# -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals from django.http import HttpResponse from django.views.generic import View class DeepThoughtView(View): def get(self, request): return HttpResponse(42)
Next, open the tests/settings.py
file and add your module to INSTALLED_APPS
INSTALLED_APPS = ( <snip> 'django_foobar', )
Finally, hook up the view in the tests/urls.py
file.
from django_foobar.views import DeepThoughtView urlpatterns = [ <snip> url(r'^deepthought/$', view=DeepThoughtView.as_view(), name='django_foobar_deepthought'), ]