2012-10-30 19:53:56 +00:00
|
|
|
|
=============================================
|
|
|
|
|
Advanced tutorial: How to write reusable apps
|
|
|
|
|
=============================================
|
|
|
|
|
|
2023-02-07 14:26:37 +00:00
|
|
|
|
This advanced tutorial begins where :doc:`Tutorial 8 </intro/tutorial08>`
|
2021-07-23 06:48:16 +00:00
|
|
|
|
left off. We'll be turning our web-poll into a standalone Python package
|
2013-03-04 11:05:11 +00:00
|
|
|
|
you can reuse in new projects and share with other people.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2016-03-28 18:26:55 +00:00
|
|
|
|
If you haven't recently completed Tutorials 1–7, we encourage you to review
|
2012-10-30 19:53:56 +00:00
|
|
|
|
these so that your example project matches the one described below.
|
|
|
|
|
|
|
|
|
|
Reusability matters
|
|
|
|
|
===================
|
|
|
|
|
|
|
|
|
|
It's a lot of work to design, build, test and maintain a web application. Many
|
|
|
|
|
Python and Django projects share common problems. Wouldn't it be great if we
|
|
|
|
|
could save some of this repeated work?
|
|
|
|
|
|
|
|
|
|
Reusability is the way of life in Python. `The Python Package Index (PyPI)
|
2018-04-17 22:19:29 +00:00
|
|
|
|
<https://pypi.org/>`_ has a vast range of packages you can use in your own
|
|
|
|
|
Python programs. Check out `Django Packages <https://djangopackages.org>`_ for
|
|
|
|
|
existing reusable apps you could incorporate in your project. Django itself is
|
2019-06-17 14:54:55 +00:00
|
|
|
|
also a normal Python package. This means that you can take existing Python
|
2018-04-17 22:19:29 +00:00
|
|
|
|
packages or Django apps and compose them into your own web project. You only
|
|
|
|
|
need to write the parts that make your project unique.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
|
|
|
|
Let's say you were starting a new project that needed a polls app like the one
|
|
|
|
|
we've been working on. How do you make this app reusable? Luckily, you're well
|
2019-03-30 01:53:03 +00:00
|
|
|
|
on the way already. In :doc:`Tutorial 1 </intro/tutorial01>`, we saw how we
|
2012-10-30 19:53:56 +00:00
|
|
|
|
could decouple polls from the project-level URLconf using an ``include``.
|
|
|
|
|
In this tutorial, we'll take further steps to make the app easy to use in new
|
|
|
|
|
projects and ready to publish for others to install and use.
|
|
|
|
|
|
|
|
|
|
.. admonition:: Package? App?
|
|
|
|
|
|
2016-05-08 22:07:43 +00:00
|
|
|
|
A Python :term:`package` provides a way of grouping related Python code for
|
|
|
|
|
easy reuse. A package contains one or more files of Python code (also known
|
|
|
|
|
as "modules").
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
|
|
|
|
A package can be imported with ``import foo.bar`` or ``from foo import
|
|
|
|
|
bar``. For a directory (like ``polls``) to form a package, it must contain
|
|
|
|
|
a special file ``__init__.py``, even if this file is empty.
|
|
|
|
|
|
2019-06-17 14:54:55 +00:00
|
|
|
|
A Django *application* is a Python package that is specifically intended
|
|
|
|
|
for use in a Django project. An application may use common Django
|
2013-12-24 15:28:31 +00:00
|
|
|
|
conventions, such as having ``models``, ``tests``, ``urls``, and ``views``
|
|
|
|
|
submodules.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
|
|
|
|
Later on we use the term *packaging* to describe the process of making a
|
|
|
|
|
Python package easy for others to install. It can be a little confusing, we
|
|
|
|
|
know.
|
|
|
|
|
|
2013-02-07 10:51:25 +00:00
|
|
|
|
Your project and your reusable app
|
|
|
|
|
==================================
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2023-02-09 15:48:46 +00:00
|
|
|
|
After the previous tutorials, our project should look like this:
|
|
|
|
|
|
|
|
|
|
.. code-block:: text
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
|
|
|
|
mysite/
|
|
|
|
|
manage.py
|
|
|
|
|
mysite/
|
|
|
|
|
__init__.py
|
|
|
|
|
settings.py
|
|
|
|
|
urls.py
|
2019-12-05 07:38:39 +00:00
|
|
|
|
asgi.py
|
2012-10-30 19:53:56 +00:00
|
|
|
|
wsgi.py
|
|
|
|
|
polls/
|
|
|
|
|
__init__.py
|
Simplified default project template.
Squashed commit of:
commit 508ec9144b35c50794708225b496bde1eb5e60aa
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue Jan 29 22:50:55 2013 +0100
Tweaked default settings file.
* Explained why BASE_DIR exists.
* Added a link to the database configuration options, and put it in its
own section.
* Moved sensitive settings that must be changed for production at the
top.
commit 6515fd2f1aa73a86dc8dbd2ccf512ddb6b140d57
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue Jan 29 14:35:21 2013 +0100
Documented the simplified app & project templates in the changelog.
commit 2c5b576c2ea91d84273a019b3d0b3b8b4da72f23
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue Jan 29 13:59:27 2013 +0100
Minor fixes in tutorials 5 and 6.
commit 55a51531be8104f21b3cca3f6bf70b0a7139a041
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue Jan 29 13:51:11 2013 +0100
Updated tutorial 2 for the new project template.
commit 29ddae87bdaecff12dd31b16b000c01efbde9e20
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue Jan 29 11:58:54 2013 +0100
Updated tutorial 1 for the new project template.
commit 0ecb9f6e2514cfd26a678a280d471433375101a3
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue Jan 29 11:29:13 2013 +0100
Adjusted the default URLconf detection to account for the admin.
It's now enabled by default.
commit 5fb4da0d3d09dac28dd94e3fde92b9d4335c0565
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue Jan 29 10:36:55 2013 +0100
Added security warnings for the most sensitive settings.
commit 718d84bd8ac4a42fb4b28ec93965de32680f091e
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 23:24:06 2013 +0100
Used an absolute path for the SQLite database.
This ensures the settings file works regardless of which directory
django-admin.py / manage.py is invoked from.
BASE_DIR got a +1 from a BDFL and another core dev. It doesn't involve
the concept of a "Django project"; it's just a convenient way to express
relative paths within the source code repository for non-Python files.
Thanks Jacob Kaplan-Moss for the suggestion.
commit 1b559b4bcda622e10909b68fe5cab90db6727dd9
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 23:22:40 2013 +0100
Removed STATIC_ROOT from the default settings template.
It isn't necessary in development, and it confuses beginners to no end.
Thanks Carl Meyer for the suggestion.
commit a55f141a500bb7c9a1bc259bbe1954c13b199671
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 23:21:43 2013 +0100
Removed MEDIA_ROOT/URL from default settings template.
Many sites will never deal with user-uploaded files, and MEDIA_ROOT is
complicated to explain.
Thanks Carl Meyer for the suggestion.
commit 44bf2f2441420fd9429ee9fe1f7207f92dd87e70
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 22:22:09 2013 +0100
Removed logging config.
This configuration is applied regardless of the value of LOGGING;
duplicating it in LOGGING is confusing.
commit eac747e848eaed65fd5f6f254f0a7559d856f88f
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 22:05:31 2013 +0100
Enabled the locale middleware by default.
USE_I18N is True by default, and doesn't work well without
LocaleMiddleware.
commit d806c62b2d00826dc2688c84b092627b8d571cab
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 22:03:16 2013 +0100
Enabled clickjacking protection by default.
commit 99152c30e6a15003f0b6737dc78e87adf462aacb
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 22:01:48 2013 +0100
Reorganized settings in logical sections, and trimmed comments.
commit d37ffdfcb24b7e0ec7cc113d07190f65fb12fb8a
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 16:54:11 2013 +0100
Avoided misleading TEMPLATE_DEBUG = DEBUG.
According to the docs TEMPLATE_DEBUG works only when DEBUG = True.
commit 15d9478d3a9850e85841e7cf09cf83050371c6bf
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 16:46:25 2013 +0100
Removed STATICFILES_FINDERS/TEMPLATE_LOADERS from default settings file.
Only developers with special needs ever need to change these settings.
commit 574da0eb5bfb4570883756914b4dbd7e20e1f61e
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 16:45:01 2013 +0100
Removed STATICFILES/TEMPLATES_DIRS from default settings file.
The current best practice is to put static files and templates in
applications, for easier testing and deployment.
commit 8cb18dbe56629aa1be74718a07e7cc66b4f9c9f0
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 16:24:16 2013 +0100
Removed settings related to email reporting from default settings file.
While handy for small scale projects, it isn't exactly a best practice.
commit 8ecbfcb3638058f0c49922540f874a7d802d864f
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue Jan 29 18:54:43 2013 +0100
Documented how to enable the sites framework.
commit 23fc91a6fa67d91ddd9d71b1c3e0dc26bdad9841
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 16:28:59 2013 +0100
Disabled the sites framework by default.
RequestSite does the job for single-domain websites.
commit c4d82eb8afc0eb8568bf9c4d12644272415e3960
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue Jan 29 00:08:33 2013 +0100
Added a default admin.py to the application template.
Thanks Ryan D Hiebert for the suggestion.
commit 4071dc771e5c44b1c5ebb9beecefb164ae465e22
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 10:59:49 2013 +0100
Enabled the admin by default.
Everyone uses the admin.
commit c807a31f8d89e7e7fd97380e3023f7983a8b6fcb
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 10:57:05 2013 +0100
Removed admindocs from default project template.
commit 09e4ce0e652a97da1a9e285046a91c8ad7a9189c
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 16:32:52 2013 +0100
Added links to the settings documentation.
commit 5b8f5eaef364eb790fcde6f9e86f7d266074cca8
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 11:06:54 2013 +0100
Used a significant example for URLconf includes.
commit 908e91d6fcee2a3cb51ca26ecdf12a6a24e69ef8
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 16:22:31 2013 +0100
Moved code comments about WSGI to docs, and rewrote said docs.
commit 50417e51996146f891d08ca8b74dcc736a581932
Author: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Mon Jan 28 15:51:50 2013 +0100
Normalized the default application template.
Removed the default test that 1 + 1 = 2, because it's been committed
way too many times, in too many projects.
Added an import of `render` for views, because the first view will
often be:
def home(request):
return render(request, "mysite/home.html")
2013-01-28 14:51:50 +00:00
|
|
|
|
admin.py
|
2020-01-16 13:51:27 +00:00
|
|
|
|
apps.py
|
2014-08-02 01:32:53 +00:00
|
|
|
|
migrations/
|
|
|
|
|
__init__.py
|
|
|
|
|
0001_initial.py
|
2012-10-30 19:53:56 +00:00
|
|
|
|
models.py
|
2013-03-04 11:05:11 +00:00
|
|
|
|
static/
|
2013-06-28 07:43:14 +00:00
|
|
|
|
polls/
|
2013-04-21 13:52:02 +00:00
|
|
|
|
images/
|
2024-01-22 04:25:28 +00:00
|
|
|
|
background.png
|
2013-04-21 13:52:02 +00:00
|
|
|
|
style.css
|
2012-10-30 19:53:56 +00:00
|
|
|
|
templates/
|
|
|
|
|
polls/
|
|
|
|
|
detail.html
|
|
|
|
|
index.html
|
|
|
|
|
results.html
|
2013-04-21 13:52:02 +00:00
|
|
|
|
tests.py
|
2012-10-30 19:53:56 +00:00
|
|
|
|
urls.py
|
|
|
|
|
views.py
|
2013-02-23 14:19:32 +00:00
|
|
|
|
templates/
|
2013-02-07 10:51:25 +00:00
|
|
|
|
admin/
|
|
|
|
|
base_site.html
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2016-02-04 06:27:16 +00:00
|
|
|
|
You created ``mysite/templates`` in :doc:`Tutorial 7 </intro/tutorial07>`,
|
2013-02-07 10:51:25 +00:00
|
|
|
|
and ``polls/templates`` in :doc:`Tutorial 3 </intro/tutorial03>`. Now perhaps
|
|
|
|
|
it is clearer why we chose to have separate template directories for the
|
|
|
|
|
project and application: everything that is part of the polls application is in
|
|
|
|
|
``polls``. It makes the application self-contained and easier to drop into a
|
|
|
|
|
new project.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
|
|
|
|
The ``polls`` directory could now be copied into a new Django project and
|
|
|
|
|
immediately reused. It's not quite ready to be published though. For that, we
|
|
|
|
|
need to package the app to make it easy for others to install.
|
|
|
|
|
|
|
|
|
|
.. _installing-reusable-apps-prerequisites:
|
|
|
|
|
|
|
|
|
|
Installing some prerequisites
|
|
|
|
|
=============================
|
|
|
|
|
|
|
|
|
|
The current state of Python packaging is a bit muddled with various tools. For
|
2023-04-16 23:14:09 +00:00
|
|
|
|
this tutorial, we're going to use :pypi:`setuptools` to build our package. It's
|
|
|
|
|
the recommended packaging tool (merged with the ``distribute`` fork). We'll
|
|
|
|
|
also be using :pypi:`pip` to install and uninstall it. You should install these
|
2012-10-30 19:53:56 +00:00
|
|
|
|
two packages now. If you need help, you can refer to :ref:`how to install
|
2013-11-15 19:06:32 +00:00
|
|
|
|
Django with pip<installing-official-release>`. You can install ``setuptools``
|
2012-10-30 19:53:56 +00:00
|
|
|
|
the same way.
|
|
|
|
|
|
|
|
|
|
Packaging your app
|
|
|
|
|
==================
|
|
|
|
|
|
|
|
|
|
Python *packaging* refers to preparing your app in a specific format that can
|
|
|
|
|
be easily installed and used. Django itself is packaged very much like
|
|
|
|
|
this. For a small app like polls, this process isn't too difficult.
|
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
#. First, create a parent directory for the package, outside of your Django
|
2012-10-30 19:53:56 +00:00
|
|
|
|
project. Call this directory ``django-polls``.
|
|
|
|
|
|
2013-09-23 22:23:47 +00:00
|
|
|
|
.. admonition:: Choosing a name for your app
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
When choosing a name for your package, check PyPI to avoid naming
|
|
|
|
|
conflicts with existing packages. We recommend using a ``django-``
|
|
|
|
|
prefix for package names, to identify your package as specific to
|
|
|
|
|
Django, and a corresponding ``django_`` prefix for your module name. For
|
|
|
|
|
example, the ``django-ratelimit`` package contains the
|
|
|
|
|
``django_ratelimit`` module.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2013-12-24 15:28:31 +00:00
|
|
|
|
Application labels (that is, the final part of the dotted path to
|
|
|
|
|
application packages) *must* be unique in :setting:`INSTALLED_APPS`.
|
|
|
|
|
Avoid using the same label as any of the Django :doc:`contrib packages
|
|
|
|
|
</ref/contrib/index>`, for example ``auth``, ``admin``, or
|
2013-12-05 13:45:49 +00:00
|
|
|
|
``messages``.
|
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
#. Move the ``polls`` directory into ``django-polls`` directory, and rename it
|
|
|
|
|
to ``django_polls``.
|
|
|
|
|
|
|
|
|
|
#. Edit ``django_polls/apps.py`` so that :attr:`~.AppConfig.name` refers to the
|
|
|
|
|
new module name and add :attr:`~.AppConfig.label` to give a short name for
|
|
|
|
|
the app:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
:caption: ``django-polls/django_polls/apps.py``
|
|
|
|
|
|
|
|
|
|
from django.apps import AppConfig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PollsConfig(AppConfig):
|
|
|
|
|
default_auto_field = "django.db.models.BigAutoField"
|
|
|
|
|
name = "django_polls"
|
|
|
|
|
label = "polls"
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2018-11-15 18:54:28 +00:00
|
|
|
|
#. Create a file ``django-polls/README.rst`` with the following contents:
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2018-09-10 17:00:34 +00:00
|
|
|
|
.. code-block:: rst
|
2022-05-31 05:40:54 +00:00
|
|
|
|
:caption: ``django-polls/README.rst``
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
============
|
|
|
|
|
django-polls
|
|
|
|
|
============
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
django-polls is a Django app to conduct web-based polls. For each
|
|
|
|
|
question, visitors can choose between a fixed number of answers.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2013-09-23 22:23:47 +00:00
|
|
|
|
Detailed documentation is in the "docs" directory.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2013-09-23 22:23:47 +00:00
|
|
|
|
Quick start
|
|
|
|
|
-----------
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2013-09-23 22:23:47 +00:00
|
|
|
|
1. Add "polls" to your INSTALLED_APPS setting like this::
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2015-01-21 16:55:57 +00:00
|
|
|
|
INSTALLED_APPS = [
|
2023-01-23 20:29:05 +00:00
|
|
|
|
...,
|
2024-01-03 21:21:10 +00:00
|
|
|
|
"django_polls",
|
2015-01-21 16:55:57 +00:00
|
|
|
|
]
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2013-09-23 22:23:47 +00:00
|
|
|
|
2. Include the polls URLconf in your project urls.py like this::
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
path("polls/", include("django_polls.urls")),
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
3. Run ``python manage.py migrate`` to create the models.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
4. Start the development server and visit the admin to create a poll.
|
2013-09-23 22:23:47 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
5. Visit the ``/polls/`` URL to participate in the poll.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2018-11-15 18:54:28 +00:00
|
|
|
|
#. Create a ``django-polls/LICENSE`` file. Choosing a license is beyond the
|
2013-09-23 22:23:47 +00:00
|
|
|
|
scope of this tutorial, but suffice it to say that code released publicly
|
|
|
|
|
without a license is *useless*. Django and many Django-compatible apps are
|
|
|
|
|
distributed under the BSD license; however, you're free to pick your own
|
|
|
|
|
license. Just be aware that your licensing choice will affect who is able
|
|
|
|
|
to use your code.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-04 22:05:05 +00:00
|
|
|
|
#. Next we'll create the ``pyproject.toml`` file which details how to build and
|
|
|
|
|
install the app. A full explanation of this file is beyond the scope of this
|
|
|
|
|
tutorial, but the `Python Packaging User Guide
|
|
|
|
|
<https://packaging.python.org/guides/writing-pyproject-toml/>`_ has a good
|
|
|
|
|
explanation. Create the ``django-polls/pyproject.toml`` file with the
|
2021-02-11 11:44:38 +00:00
|
|
|
|
following contents:
|
|
|
|
|
|
|
|
|
|
.. code-block:: toml
|
2024-01-04 22:05:05 +00:00
|
|
|
|
:caption: ``django-polls/pyproject.toml``
|
|
|
|
|
|
|
|
|
|
[build-system]
|
|
|
|
|
requires = ["setuptools>=61.0"]
|
|
|
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
|
|
|
|
|
|
[project]
|
|
|
|
|
name = "django-polls"
|
|
|
|
|
version = "0.1"
|
|
|
|
|
dependencies = [
|
|
|
|
|
"django>=X.Y", # Replace "X.Y" as appropriate
|
|
|
|
|
]
|
|
|
|
|
description = "A Django app to conduct web-based polls."
|
|
|
|
|
readme = "README.rst"
|
|
|
|
|
requires-python = ">= 3.10"
|
|
|
|
|
authors = [
|
|
|
|
|
{name = "Your Name", email = "yourname@example.com"},
|
|
|
|
|
]
|
|
|
|
|
classifiers = [
|
|
|
|
|
"Environment :: Web Environment",
|
|
|
|
|
"Framework :: Django",
|
|
|
|
|
"Framework :: Django :: X.Y", # Replace "X.Y" as appropriate
|
|
|
|
|
"Intended Audience :: Developers",
|
|
|
|
|
"License :: OSI Approved :: BSD License",
|
|
|
|
|
"Operating System :: OS Independent",
|
|
|
|
|
"Programming Language :: Python",
|
|
|
|
|
"Programming Language :: Python :: 3",
|
|
|
|
|
"Programming Language :: Python :: 3 :: Only",
|
|
|
|
|
"Programming Language :: Python :: 3.10",
|
|
|
|
|
"Programming Language :: Python :: 3.11",
|
|
|
|
|
"Programming Language :: Python :: 3.12",
|
|
|
|
|
"Topic :: Internet :: WWW/HTTP",
|
|
|
|
|
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
[project.urls]
|
|
|
|
|
Homepage = "https://www.example.com/"
|
|
|
|
|
|
|
|
|
|
#. Many common files and Python modules and packages are included in the
|
|
|
|
|
package by default. To include additional files, we'll need to create a
|
|
|
|
|
``MANIFEST.in`` file. To include the templates and static files, create a
|
|
|
|
|
file ``django-polls/MANIFEST.in`` with the following contents:
|
2013-09-23 22:23:47 +00:00
|
|
|
|
|
2018-09-10 17:00:34 +00:00
|
|
|
|
.. code-block:: text
|
2024-01-04 22:05:05 +00:00
|
|
|
|
:caption: ``django-polls/MANIFEST.in``
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-04 22:05:05 +00:00
|
|
|
|
recursive-include django_polls/static *
|
|
|
|
|
recursive-include django_polls/templates *
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2018-11-15 18:54:28 +00:00
|
|
|
|
#. It's optional, but recommended, to include detailed documentation with your
|
2012-10-30 19:53:56 +00:00
|
|
|
|
app. Create an empty directory ``django-polls/docs`` for future
|
2024-01-04 22:05:05 +00:00
|
|
|
|
documentation.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
|
|
|
|
Note that the ``docs`` directory won't be included in your package unless
|
|
|
|
|
you add some files to it. Many Django apps also provide their documentation
|
2013-12-08 17:39:26 +00:00
|
|
|
|
online through sites like `readthedocs.org <https://readthedocs.org>`_.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-04 22:05:05 +00:00
|
|
|
|
#. Check that the :pypi:`build` package is installed (``python -m pip install
|
|
|
|
|
build``) and try building your package by running ``python -m build`` inside
|
2024-01-03 21:21:10 +00:00
|
|
|
|
``django-polls``. This creates a directory called ``dist`` and builds your
|
2024-01-04 22:05:05 +00:00
|
|
|
|
new package into source and binary formats, ``django-polls-0.1.tar.gz`` and
|
|
|
|
|
``django_polls-0.1-py3-none-any.whl``.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2014-10-24 22:58:31 +00:00
|
|
|
|
For more information on packaging, see Python's `Tutorial on Packaging and
|
2019-03-21 14:04:15 +00:00
|
|
|
|
Distributing Projects
|
|
|
|
|
<https://packaging.python.org/tutorials/packaging-projects/>`_.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
|
|
|
|
Using your own package
|
|
|
|
|
======================
|
|
|
|
|
|
|
|
|
|
Since we moved the ``polls`` directory out of the project, it's no longer
|
|
|
|
|
working. We'll now fix this by installing our new ``django-polls`` package.
|
|
|
|
|
|
2012-10-31 23:56:53 +00:00
|
|
|
|
.. admonition:: Installing as a user library
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2012-10-31 23:56:53 +00:00
|
|
|
|
The following steps install ``django-polls`` as a user library. Per-user
|
|
|
|
|
installs have a lot of advantages over installing the package system-wide,
|
|
|
|
|
such as being usable on systems where you don't have administrator access
|
|
|
|
|
as well as preventing the package from affecting system services and other
|
2013-07-13 17:29:11 +00:00
|
|
|
|
users of the machine.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2012-10-31 23:56:53 +00:00
|
|
|
|
Note that per-user installations can still affect the behavior of system
|
2020-06-02 09:45:44 +00:00
|
|
|
|
tools that run as that user, so using a virtual environment is a more robust
|
|
|
|
|
solution (see below).
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2018-11-15 18:54:28 +00:00
|
|
|
|
#. To install the package, use pip (you already :ref:`installed it
|
2023-02-09 15:48:46 +00:00
|
|
|
|
<installing-reusable-apps-prerequisites>`, right?):
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2023-02-09 15:48:46 +00:00
|
|
|
|
.. code-block:: shell
|
|
|
|
|
|
|
|
|
|
python -m pip install --user django-polls/dist/django-polls-0.1.tar.gz
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
#. Update ``mysite/settings.py`` to point to the new module name::
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
INSTALLED_APPS = [
|
|
|
|
|
"django_polls.apps.PollsConfig",
|
|
|
|
|
...,
|
|
|
|
|
]
|
2023-02-09 15:48:46 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
#. Update ``mysite/urls.py`` to point to the new module name::
|
|
|
|
|
|
|
|
|
|
urlpatterns = [
|
|
|
|
|
path("polls/", include("django_polls.urls")),
|
|
|
|
|
...,
|
|
|
|
|
]
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
#. Run the development server to confirm the project continues to work.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
|
|
|
|
Publishing your app
|
|
|
|
|
===================
|
|
|
|
|
|
|
|
|
|
Now that we've packaged and tested ``django-polls``, it's ready to share with
|
|
|
|
|
the world! If this wasn't just an example, you could now:
|
|
|
|
|
|
|
|
|
|
* Email the package to a friend.
|
|
|
|
|
|
2015-11-15 12:05:15 +00:00
|
|
|
|
* Upload the package on your website.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2014-10-24 22:58:31 +00:00
|
|
|
|
* Post the package on a public repository, such as `the Python Package Index
|
|
|
|
|
(PyPI)`_. `packaging.python.org <https://packaging.python.org>`_ has `a good
|
2019-03-21 14:04:15 +00:00
|
|
|
|
tutorial <https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives>`_
|
2014-10-24 22:58:31 +00:00
|
|
|
|
for doing this.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2020-06-02 09:45:44 +00:00
|
|
|
|
Installing Python packages with a virtual environment
|
|
|
|
|
=====================================================
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
2024-01-03 21:21:10 +00:00
|
|
|
|
Earlier, we installed ``django-polls`` as a user library. This has some
|
2012-10-30 19:53:56 +00:00
|
|
|
|
disadvantages:
|
|
|
|
|
|
2012-10-31 23:56:53 +00:00
|
|
|
|
* Modifying the user libraries can affect other Python software on your system.
|
2012-10-30 19:53:56 +00:00
|
|
|
|
|
|
|
|
|
* You won't be able to run multiple versions of this package (or others with
|
|
|
|
|
the same name).
|
|
|
|
|
|
|
|
|
|
Typically, these situations only arise once you're maintaining several Django
|
2020-06-02 09:45:44 +00:00
|
|
|
|
projects. When they do, the best solution is to use :doc:`venv
|
|
|
|
|
<python:tutorial/venv>`. This tool allows you to maintain multiple isolated
|
|
|
|
|
Python environments, each with its own copy of the libraries and package
|
|
|
|
|
namespace.
|