| 1 | ===================================== |
| 2 | Writing your first Django app, part 5 |
| 3 | ===================================== |
| 4 | |
| 5 | This tutorial begins where :doc:`Tutorial 4 </intro/tutorial04>` left |
| 6 | off. We'll be turning our Web-poll into a stand-alone Python package. |
| 7 | |
| 8 | .. Draft outline: |
| 9 | |
| 10 | .. * motivation |
| 11 | .. * what is a python package? |
| 12 | .. * what is an external package? |
| 13 | |
| 14 | .. * preparing |
| 15 | .. * moving templates into your app |
| 16 | .. * parent directory |
| 17 | .. * adding package boilerplate |
| 18 | .. * link to packaging docs |
| 19 | .. * package builder |
| 20 | |
| 21 | .. * using the package |
| 22 | .. * where to put it |
| 23 | |
| 24 | .. * publishing |
| 25 | .. * options for publishing |
| 26 | .. * link to docs on publishing to PyPI |
| 27 | |
| 28 | Python packages and reusable apps |
| 29 | ================================== |
| 30 | |
| 31 | Django really is just Python. This means that you can make use of existing |
| 32 | Python packages in your project. You can also take parts of your projects and |
| 33 | reuse or share them. |
| 34 | |
| 35 | .. note:: |
| 36 | |
| 37 | A Python `package <http://docs.python.org/tutorial/modules.html#packages>`_ |
| 38 | is a way of grouping related Python code for easy reuse. A package contains |
| 39 | one or more files of Python code (also known as "modules"). |
| 40 | |
| 41 | A Django *app* is nothing more than a Python package intended for use in a |
| 42 | Django project. To simplify this, an app may use common Django conventions, |
| 43 | such as having a ``models.py`` file. |
| 44 | |
| 45 | One of Django's most powerful features is the concept of *reusable apps*. The |
| 46 | idea is that rather than rebuilding every new Django project from scratch, you |
| 47 | can make use of existing packages that you, and others, have written. |
| 48 | |
| 49 | In fact, we're halfway there already. The Polls app we've been working on is |
| 50 | already a Python package. We know this because it can be imported with ``import |
| 51 | polls`` (since it contains an ``__init__.py`` file). In the previous tutorials, |
| 52 | we began making Polls reusable by decoupling it from the project-level URLconf. |
| 53 | |
| 54 | In this tutorial, we'll take further steps to make the app easily to use in new |
| 55 | projects and ready to publish for others to install and use. |
| 56 | |
| 57 | Completing your reusable app |
| 58 | ============================ |
| 59 | |
| 60 | Currently the |
| 61 | |
| 62 | Inside ``mysite/polls``, create the directory ``templates`` and *inside* that, |
| 63 | the directory ``polls``. Move the ``index.html`` and ``detail.html`` templates |
| 64 | into ``templates/polls``. This allows the app's templates to be distributed |
| 65 | with the app. Confirm that your poll Web site still works correctly. |
| 66 | |
| 67 | Your project should now look like this:: |
| 68 | |
| 69 | mysite/ |
| 70 | polls/ |
| 71 | admin.py |
| 72 | templates/ |
| 73 | polls/ |
| 74 | detail.html |
| 75 | index.html |
| 76 | __init__.py |
| 77 | models.py |
| 78 | tests.py |
| 79 | urls.py |
| 80 | views.py |
| 81 | __init__.py |
| 82 | manage.py |
| 83 | settings.py |
| 84 | urls.py |
| 85 | |
| 86 | .. NOTE:: Why create a ``polls`` directory under templates when we're already |
| 87 | inside the Polls app? This directory is needed to avoid conflicts because of |
| 88 | how Django's ``app_directories`` template loader works. |
| 89 | |
| 90 | You now have a package that could be copied into new Django projects and |
| 91 | immediately reused. It's not yet ready to be published though. For that, we |
| 92 | need to package the app to make it easy for others to install. |
| 93 | |
| 94 | Packaging for external use |
| 95 | ========================== |
| 96 | |
| 97 | Python packaging isn't as hard as it sounds, especially for such a small app. |
| 98 | |
| 99 | * Firstly, create a parent directory for ``polls``, outside of your Django |
| 100 | project. Call this directory ``django-polls``. |
| 101 | |
| 102 | * Move the ``polls`` directory into the ``django-polls`` directory. |
| 103 | |
| 104 | * Create a file ``django-polls/README.txt``:: |
| 105 | |
| 106 | ===== |
| 107 | Polls |
| 108 | ===== |
| 109 | |
| 110 | Polls is a simple Django app to conduct Web-based polls. For each |
| 111 | question, visitors can choose between a fixed number of answers. |
| 112 | |
| 113 | * Create a file ``django-polls/setup.py`` with the following contents:: |
| 114 | |
| 115 | from distutils.core import setup |
| 116 | |
| 117 | setup( |
| 118 | name='django-polls', |
| 119 | version='0.1', |
| 120 | packages=['polls',], |
| 121 | long_description=open('README.txt').read(), |
| 122 | url='http://www.example.com/', |
| 123 | author='Your Name', |
| 124 | author_email='yourname@example.com', |
| 125 | ) |
| 126 | |
| 127 | * Try building your package with ``python setup.py sdist`` (run from inside |
| 128 | ``django-polls``. This creates a directory called ``dist`` and builds |
| 129 | your new package, ``django-polls-0.1.tar.gz``. |
| 130 | |
| 131 | For more information on packaging, see `The Hitchhiker's Guide to Packaging |
| 132 | <http://guide.python-distribute.org/quickstart.html>`_. |
| 133 | |
| 134 | Using your own package |
| 135 | ====================== |
| 136 | |
| 137 | Since we moved the ``polls`` directory out of the project, it's no longer |
| 138 | working. We'll now fix this by installing our new ``django-polls`` package. |
| 139 | |
| 140 | .. NOTE:: The following steps install ``django-polls`` as a system library. In |
| 141 | general, it's best to avoid messing with your system libraries to avoid |
| 142 | breaking things. For this simple example though, the risk is low and it will |
| 143 | help with understanding packaging. We'll explain how to uninstall in |
| 144 | step 4. |
| 145 | |
| 146 | For experienced users, a neater way to manage your packages is to use |
| 147 | "virtualenv" (see below). |
| 148 | |
| 149 | 1. Inside ``django-polls/dist``, untar the new package |
| 150 | ``django-polls-0.1.tar.gz`` (e.g. ``tar xzvf django-polls-0.1.tar.gz``). If |
| 151 | you're using Windows, you can download the command-line tool bsdtar_ to do |
| 152 | this, or you can use a GUI-based tool such as 7-zip_. |
| 153 | |
| 154 | 2. Change into the directory created in step 1 (e.g. ``cd django-polls``). |
| 155 | |
| 156 | 3. If you're using GNU/Linux, Mac OS X or some other flavor of Unix, enter the |
| 157 | command ``sudo python setup.py install`` at the shell prompt. If you're |
| 158 | using Windows, start up a command shell with administrator privileges and |
| 159 | run the command ``setup.py install``. |
| 160 | |
| 161 | With luck, your Django project should now work correctly again. Run the |
| 162 | server again to confirm this. |
| 163 | |
| 164 | 4. To uninstall the package, delete the directory ``polls`` and the file |
| 165 | ``django_polls-0.1.egg-info`` from your system libraries. On GNU/Linux and |
| 166 | Mac OS these files live in ``/usr/local/lib/python2.X/dist-packages``, and |
| 167 | on Windows, in ``C:\Python2X\Lib\site-packages`` (where *X* is the Python |
| 168 | minor version number). You will need administrator privileges. |
| 169 | |
| 170 | .. _bsdtar: http://gnuwin32.sourceforge.net/packages/bsdtar.htm |
| 171 | .. _7-zip: http://www.7-zip.org/ |
| 172 | |
| 173 | Publishing your app |
| 174 | =================== |
| 175 | |
| 176 | Now that we've packaged and tested ``django-polls``, it's ready to share with |
| 177 | the world! If this wasn't just an example, you might now want to: |
| 178 | |
| 179 | * Email the package to a friend. |
| 180 | |
| 181 | * Upload the package on your Web site. |
| 182 | |
| 183 | * Post the package on a public repository, such as `The Python Package |
| 184 | Index (PyPI) |
| 185 | <http://guide.python-distribute.org/contributing.html#pypi-info>`_. |
| 186 | |
| 187 | For more information on PyPI, see the `Quickstart |
| 188 | <http://guide.python-distribute.org/quickstart.html#register-your-package-with-the-python-package-index-pypi>`_ |
| 189 | section of The Hitchhiker's Guide to Packaging. |
| 190 | |
| 191 | Installing Python packages with virtualenv |
| 192 | ========================================== |
| 193 | |
| 194 | Earlier, we installed the Polls app as a system library. This has some |
| 195 | disadvantages: |
| 196 | |
| 197 | * Modifying the system libraries can affect other Python software on your |
| 198 | system. |
| 199 | |
| 200 | * You won't be able to run multiple version of this package (or others with |
| 201 | the same name). |
| 202 | |
| 203 | Typically, these situations only arise once you're maintaining several Django |
| 204 | projects. When they do, the best solution is to use `virtualenv |
| 205 | <http://www.virtualenv.org/>`_. This tool allows you to maintain multiple |
| 206 | isolated Python environments, each with its own copy of the libraries and |
| 207 | package namespace. |
| 208 | |
| 209 | Further information |
| 210 | =================== |
| 211 | |
| 212 | For more on writing reusable apps, see `What is a reusable app? |
| 213 | <http://ericholscher.com/projects/django-conventions/app/>`_ by Eric |
| 214 | Holsher. For a collection of reusable apps to use in your own projects, see the |
| 215 | `Pinax <http://pinaxproject.com/>`_ project. |
| 216 | |
| 217 | The tutorial ends here for the time being. In the meantime, you might want to |
| 218 | check out some pointers on :doc:`where to go from here </intro/whatsnext>`. |