How to create your first Django library

Page Status:Complete
Last Reviewed:2017-02-11

This is a guide how to create first third-party django library or application, attempting to be kindly. Django documentation tell you way to create django’s projects and applications. But there isn’t (perhaps) way to distribute applications like django-cms, django-blog-zinnia. So, I’ll show you it.

On the end, the layout of the package will be like this:

django-myapp
|-- __init__.py
|-- MANIFEST.in
|-- README.rst
|-- LICENSE
|-- setup.py
|-- test_settings.py
|-- myapp
|   |-- __init__.py
|   |-- models.py
|   |-- views.py
|   `-- tests.py
`-- tox.ini

Whole example project described on this page is on Github: django-myapp.

This guide includes about packaging or python environments. If you have created couple of python libraries, you can skip over some steps to 3. Way to run tests without projects. But at least, I expect you to finish the tutorial of django’s document and create some apps.

1. Create your application

When you create third-party library, you won’t need to create a project. Just create your application by using startapp sub-command. But wait. you will distribute this application, so you need a parent directory to package it like this:

mkdir django-myapp
cd django-myapp
django-admin.py startapp myapp

OK, just it. Write your codes as same as way you learned at tutorial. “Can’t run tests”...? Yeah, I know it. and I’ll show you about it later.

And you need to write README and LICENSE file to describe about your package. I won’t use packages without README or documentation:

touch README.rst
touch LICENSE

Also It’s good idea to manage packages by using some VCS like git:

git init

For more detail about git, refer the git official site.

2. Packaging

To distribute your app/lib, make it as a package. Just thing you need to do is putting setup.py file under the django-myapp directory meaning next to myapp directory.

The contents of this file will contain information about your package, name, version, description, required packages, and so on:

import os
from setuptools import setup

here = os.path.abspath(os.path.dirname(__file__))
README = open(os.path.join(here, 'README.rst')).read()

setup(
    name='django-myapp',
    version='0.1',
    packages=['myapp'],
    description='A line of description',
    long_description=README,
    author='yourname',
    author_email='yourname@example.com',
    url='https://github.com/yourname/django-myapp/',
    license='MIT',
    install_requires=[
        'Django>=1.6,<1.7',
    ]
)

I recommend you to write them at least.

name
The name of package like django-cms. This name will use when you specify the package by pip. So if you name it as django-myapp, users will type pip install django-myapp.
version
Version of you package. I recommend to follow semantic versioning
packages
List of python modules you want to contain. Basically, It’s enough to specify the django application you created.
description
A line of description. It will be used, for example, on package list of PyPI.
long_description
Lines of description. Basically it’s good idea to use README file as long_description. This will be used the package page of PyPI like here django-reportmail
author
Your name.
author_email
Your email address
url
A URL for your web site of the package. Basically, it’s enough to put the URL for your repository on Github and so.
license
The name of license you want to use. I always specify ‘MIT’ meaning the MIT license
install_requires
A list of packages that your packages require. It’s django package, so it’s necessary to write ‘Django’ at least.

All right.

And then, It requires MANIFEST.in file on the project directory to specify which files you want to distribute:

include *.txt *.ini *.cfg *.rst
recursive-include myapp *.ico *.png *.css *.gif *.jpg *.txt *.js *.html *.xml

Without this file, templates of your application won’t be included the package. For more detail, refer official doc about specifying the files to distribute

It’s over. After created setup.py, run this command to register this new package for development:

python setup.py develop

For more detail about setup.py, please refer another documents or packages. Python Packaging User Guide will help you. And I imitated setup.py of some another packages. Actually I haven’t read documents so much.

If you want to upload your package to PyPI. just register the application and upload:

python setup.py register
python setup.py sdist upload

From the second time, it’s enough to run the second line. Also you can refer the doc about uploading on Python Packaging User Guide

3. Way to run tests without projects

Basically django always requires ‘projects’ for all of actions. then how can we run tests? actually It’s easy, you can just use django-admin.py command and specify settings file for testing. First, create the settings for testing on the project root:

touch test_settings.py

And the contents of the file will be like this:

INSTALLED_APPS = (
    'myapp',
)
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': ':memory:',
    }
}
SECRET_KEY = "secret_key_for_testing"

Ya, it’s easy. Of cause you can put some additional settings to correspond to tests of your application. And this article about optimizing your tests in Django will be helpful.

To run the test by using the setting, type this command at the project root:

django-admin.py test --settings=test_settings

4. Use tox

If you want the package to support multiple versions of Python or Django, It’s the best idea to use tox.

Ok, let’s consider a case which supporting two versions of Python, Python2.7 and Python3.3. Put a file name tox.ini on the package root:

touch tox.ini

And then, write setting like this:

[tox]
envlist = py27, py33, flake8

[testenv]
commands =
    pip install -e .
    django-admin.py test --settings=test_settings

To run those tests, install tox and type like this:

pip install tox
tox

Three bunches of tests will run. tests with Python2.7, Python3.3 and flake8 testing to check syntax of your codes.

For more about tox and flake8, refer the official documentations.

Conclusion

It’s over.

If you have some question or want to point out my mistake please Contact me. I’ll answer and fix this page as soon as I can.