# Django 6.0.7 문서

# 심화 튜토리얼: 재사용 가능한 앱을 만드는 법

This advanced tutorial begins where Tutorial 8 left off. We’ll be turning our web-poll into a standalone Python package you can reuse in new projects and share with other people.

최근에 튜토리얼 1~8장을 완료하지 않았다면, 이를 다시 살펴보고 예제 프로젝트를 아래에서 설명하는 내용과 일치시키는 것을 권장합니다.

## 재사용의 중요성

웹 어플리케이션을 설계, 빌드, 테스트, 유지하는 것은 꽤나 큰 일입니다. 수많은 Python과 Django 프로젝트들에는 공통적인 문제가 있습니다. 만약 우리가 이러한 반복적인 작업들 중에서 몇몇을 구해낼 수 있다면 정말 멋지지 않을까요?

재사용성은 Python의 핵심 가치입니다. Python Package Index(PyPI)에는 여러분의 Python 프로그램에 사용할 수 있는 방대한 패키지가 있습니다. 여러분의 프로젝트에 활용할 수 있는 재사용 가능 앱을 Django Packages에서 확인하세요. Django는 그 자체로서 Python 패키지이기도 합니다. 이는 기존 Python 패키지 또는 Django 앱을 가져다가 당신의 웹 프로젝트에 이용할 수 있음을 의미합니다. 프로젝트만의 고유한 부분을 작성하기만 하면 됩니다.

이제 우리가 작업했던 것과 같은 설문조사 앱이 필요하여 새로운 프로젝트를 시작했다고 가정해봅시다. 어떻게 이 앱을 재사용할 수 있게 만들 수 있을까요? 운 좋게도, 여러분은 이미 방법을 알고 있습니다. 튜토리얼 1장 에서, 우리는 `include` 를 이용하여 프로젝트 수준의 URLconf에서 설문조사를 분리하는 방법을 배웠습니다. 이 튜토리얼에서는, 새로운 프로젝트에서 사용하기 쉬운 앱을 만들고 이 앱을 설치하고 사용할 다른 사람들을 위해 게시할 준비를 하기 위한 추가적인 작업을 진행할 것입니다.

패키지? 앱?

Python package는 재사용을 쉽게 하기 위해 연관된 Python 코드를 묶어 놓은 것입니다. 패키지에는 Python 코드가 들어있는 하나 이상의 파일(“모듈”이라고도 함)들이 포함되어 있습니다.

`import foo.bar` 나 `from foo import bar` 로 패키지를 import 할 수 있습니다. 디렉토리(`polls`와 같은)는 패키지를 형성하기 위해, 특별한 파일 `__init__.py`를 포함하고 있습니다, 그 파일이 빈파일일 경우에도 포함하고 있습니다.

Django 어플리케이션은 Django 프로젝트에 사용하기 위한 파이썬 패키지일 뿐입니다. 애플리케이션은 `models`, `tests`, `urls`, `views` 서브모듈들을 포함하고 있는 공통적인 Django 규칙을 이용할 수 있습니다.

여기서는 다른 사람들이 Python 패키지를 쉽게 설치할 수 있게 만드는 과정을 이르는 데 패키징이라는 용어를 사용할 것입니다. 약간 혼동될 수도 있습니다.

## 프로젝트와 재사용가능한 앱

이전 튜토리얼을 마치면, 프로젝트는 다음과 같을 것입니다.

    djangotutorial/
        manage.py
        mysite/
            __init__.py
            settings.py
            urls.py
            asgi.py
            wsgi.py
        polls/
            __init__.py
            admin.py
            apps.py
            migrations/
                __init__.py
                0001_initial.py
            models.py
            static/
                polls/
                    images/
                        background.png
                    style.css
            templates/
                polls/
                    detail.html
                    index.html
                    results.html
            tests.py
            urls.py
            views.py
        templates/
            admin/
                base_site.html

여러분은 튜토리얼 7 </intro/tutorial07>`에서 ``djangotutorial/templates``를, :doc:`Tutorial 3 </intro/tutorial03>`에서 ``polls/templates``를 생성했습니다. 이제 프로젝트와 애플리케이션의 템플릿 디렉터리를 분리한 이유가 더 명확해졌을 것입니다. ``polls` 애플리케이션과 관련된 모든 구성 요소는 ``polls``에 포함되어 있습니다. 이렇게 하면 애플리케이션이 독립적으로 구성되어 새로운 프로젝트에서도 쉽게 사용할 수 있습니다.

`polls` 디렉토리가 이제 새 Django 프로젝트로 복사되었고, 바로 재사용할 수 있습니다. 그래도 게시 할 준비가 되지 않았습니다. 이를 위해, 다른 사람들이 쉽게 설치할 수 있도록 앱을 패키지화해야합니다.

## 필수 구성 요소 설치

Python 패키징의 현재 상태는 다양한 도구들로 인해 약간 혼란스럽습니다. 이 튜토리얼에서는 패키지를 빌드하는데 setuptools`을 사용할 것입니다. 권장 패키징 도구(``distribute` 포크와 병합된)입니다. 설치하고 삭제하기 위해 pip`을 사용할 것입니다. 당신은 이제 두 패키지를 설치해야합니다. 도움이 필요하면 :ref: pip로 Django 설치하는 법 <installing-official-release>`.을 참조할 수 있습니다. 같은 방법으로 ``setuptools``도 설치할 수 있습니다.

## 앱 패키징하기

파이썬 패키징 은 쉽게 설치하고 사용할 수 있는 특별한 형식으로 앱을 준비하는 것을 의미합니다. 장고 자체도 이와 같이 패키지화되어 있습니다. 설문조사처럼 작은 앱은 이 과정이 어렵지 않습니다.

1. 첫째로, 장고 프로젝트의 외부 경로에, 패키지를 위한 부모 폴더를 만듭니다. 이 폴더를 ``django-polls``라고 부르겠습니다.

   앱 이름 선택

   패키지 이름을 정할 때 기존 패키지와의 충돌을 피하려면 PyPI를 확인하세요. 패키지 이름은 Django 전용임을 나타내기 위해 `django-` 접두사를 사용하는 것을 권장하며, 이에 맞춰 모듈 이름에는 `django_` 접두사를 사용하는 것이 좋습니다. 예를 들어 `django-ratelimit` 패키지에는 `django_ratelimit` 모듈이 포함되어 있습니다.

   어플리케이션 라벨(즉, 애플리케이션 패키지 경로의 마지막 부분)은 `INSTALLED_APPS`에서 유일한 것이어야 합니다. `auth`, `admin`, `messages` 같은 Django contrib 패키지와 동일한 라벨을 사용하지 마세요.

2. `polls` 디렉토리를 `django-polls` 디렉토리로 이동한 후, 이름을 ``django_polls``로 변경하세요.

3. :attr:`~.AppConfig.name`이 새 모듈 이름을 참조하도록 ``django_polls/apps.py``를 수정하세요. 또한 앱에 짧은 이름을 부여하려면 :attr:`~.AppConfig.label`을 추가하고, 재사용 가능한 앱의 사용자가 :setting:`DEFAULT_AUTO_FIELD`를 변경하더라도 마이그레이션에 영향을 주지 않도록 :attr:`~.AppConfig.default_auto_field`를 설정하세요.

   `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"

4. 다음과 같은 내용으로 `django-polls/README.rst`를 생성합니다:

   `django-polls/README.rst`

       ============
       django-polls
       ============

       django-polls is a Django app to conduct web-based polls. For each
       question, visitors can choose between a fixed number of answers.

       Detailed documentation is in the "docs" directory.

       Quick start
       -----------

       1. Add "polls" to your INSTALLED_APPS setting like this::

           INSTALLED_APPS = [
               ...,
               "django_polls",
           ]

       2. Include the polls URLconf in your project urls.py like this::

           path("polls/", include("django_polls.urls")),

       3. Run ``python manage.py migrate`` to create the models.

       4. Start the development server and visit the admin to create a poll.

       5. Visit the ``/polls/`` URL to participate in the poll.

5. `django-polls/LICENSE` 파일을 생성합니다. 라이선스 선택은 이 튜토리얼의 범위를 벗어나므로, 라이선스 없이 공개된 코드는 쓸모없음 을 의미한다는 것만 말해두겠습니다. Django와 많은 Django 호환 앱들이 BSD 라이센스로 배포되고 있습니다; 그러나 자신의 라이센스를 자유롭게 선택할 수 있습니다. 라이선스 선택이 누군가 여러분의 코드를 사용하는데 영향이 미칠수 있다는 사실은 알고 있어야합니다.

6. 다음으로, 앱을 빌드하고 설치하는 방법을 정의하는``pyproject.toml`` 파일을 생성합니다. 이 파일에 대한 자세한 설명은 이 튜토리얼의 범위를 벗어나지만, Python Packaging User Guide <https://packaging.python.org/guides/writing-pyproject-toml/>`_에 잘 설명되어 있습니다. 다음 내용으로 ``django-polls/pyproject.toml` 파일을 생성하세요.

   `django-polls/pyproject.toml`

       [build-system]
       requires = ["setuptools>83"]
       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"
       license = "BSD-3-Clause"
       requires-python = ">= 3.12"
       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",
           "Operating System :: OS Independent",
           "Programming Language :: Python",
           "Programming Language :: Python :: 3",
           "Programming Language :: Python :: 3 :: Only",
           "Programming Language :: Python :: 3.12",
           "Programming Language :: Python :: 3.13",
           "Programming Language :: Python :: 3.14",
           "Topic :: Internet :: WWW/HTTP",
           "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
       ]

       [project.urls]
       Homepage = "https://www.example.com/"

7. 기본적으로 여러 일반적인 파일과 Python 모듈 및 패키지가 패키지에 포함됩니다. 추가 파일을 포함하려면 `MANIFEST.in` 파일을 생성해야 합니다. 템플릿과 정적 파일을 포함하려면, 다음 내용으로 `django-polls/MANIFEST.in` 파일을 생성하세요.

   `django-polls/MANIFEST.in`

       recursive-include django_polls/static *
       recursive-include django_polls/templates *

8. 선택 사항이지만, 앱에 자세한 문서를 포함하는 것을 권장합니다. 향후 문서를 위해 빈 디렉토리 ``django-polls/docs``를 생성하세요.

   파일을 추가하지 않으면 `docs` 디렉토리는 패키지에 포함되지 않을 것입니다. 많은 Django 앱들이 readthedocs.org 같은 사이트들을 통해 온라인 문서를 제공합니다.

   Django와 Python 자체를 포함한 많은 Python 프로젝트는 Sphinx <https://www.sphinx-doc.org/en/master/usage/quickstart.html>`_를 사용하여 문서를 빌드합니다. Sphinx를 사용하기로 선택했다면, `Intersphinx <https://www.sphinx-doc.org/en/master/usage/quickstart.html#intersphinx>`_를 구성하고 프로젝트의 ``intersphinx_mapping` 설정에 Django 값을 포함하여 Django 문서로 연결할 수 있습니다:

       intersphinx_mapping = {
           # ...
           "django": (
               "https://docs.djangoproject.com/en/stable/",
               None,
           ),
       }

   이렇게 설정하면 Django 문서와 같은 방식으로 “`:attr:`django.test.TransactionTestCase.databases``”와 같은 특정 항목에 교차 링크를 걸 수 있습니다.

9. build 패키지가 설치되었는지 확인하고(`python -m pip install build`), `django-polls` 디렉토리에서 `python -m build``를 실행해 패키지를 빌드해 보세요. 그러면 ``dist``라는 디렉토리가 생성되고, 새 패키지가 소스 및 바이너리 형식(``django_polls-0.1.tar.gz`, `django_polls-0.1-py3-none-any.whl`)으로 빌드됩니다.

패키징에 관한 더 자세한 정보는 파이썬의 `프로젝트 패키징 및 배포에 관한 튜토리얼 <https://packaging.python.org/distributing/>`_을 참조하십시오.

## 여러분의 패키지 사용하기

우리가 `polls` 디렉토리를 프로젝트 바깥으로 이동했으므로, 작동하지 않을것입니다. 우리의 새 `django-polls` 패키지를 설치하여 이 문제를 해결할 것입니다.

유저 라이브러리 설치하기

다음 단계는 `django-polls` 를 사용자 라이브러리로 설치합니다. 사용자 단위 설치는 관리자권한 접근이 안되는 시스템 뿐만아니라 시스템 서비스나 다른 사용자들의 영향으로부터 패키지를 보호하는 것 같은 이점이 많습니다.

사용자별 설치는 여전히 해당 사용자로 실행되는 시스템 도구의 동작에 영향을 미칠 수 있으므로 가상 환경을 사용하는 것이 더 강력한 해결 방법입니다(아래 참조).

1. 패키지를 설치하기 위해 pip를 사용하세요 (당신은 이미 설치하였습니다. 그렇죠?),

       python -m pip install --user django-polls/dist/django_polls-0.1.tar.gz

2. ``mysite/settings.py``가 새 모듈 이름을 가리키도록 업데이트하세요:

       INSTALLED_APPS = [
           "django_polls.apps.PollsConfig",
           ...,
       ]

3. ``mysite/urls.py``가 새 모듈 이름을 가리키도록 업데이트하세요:

       urlpatterns = [
           path("polls/", include("django_polls.urls")),
           ...,
       ]

4. 프로젝트가 계속 정상적으로 동작하는지 확인하려면 개발 서버를 실행하세요.

## 앱 퍼블리싱

우리는 `django-polls` 를 패키지화하고 테스트했기에, 세계와 공유할 준비가 되었습니다. 단순한 예제가 아니면, 여러분은 이제 아래와 같은 것들을 할 수 있습니다:

- 친구에게 패키지를 이메일로 보내기

- 웹사이트에 패키지 업로드

- `the Python Package Index (PyPI)`_와 같은 공용 저장소에 패키지를 게시하세요. 이를 위한 `좋은 튜토리얼 <https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives>`_도 제공됩니다.

## 파이썬 패키지를 가상 환경으로 설치하기

앞에서 ``django-polls``를 사용자 라이브러리로 설치했습니다. 이 방식에는 몇 가지 단점이 있습니다:

- 사용자 라이브러리를 수정하면 시스템의 다른 파이썬 소프트웨어에 영향을 미칠 수 있습니다.

- 이 패키지의 여러 버전 (또는 이름이 같은 다른 버전)을 실행할 수 없습니다.

일반적으로 이러한 상황들은 여러 Django 프로젝트를 유지보수할 때만 발생합니다. 이러한 경우, 최선의 해결책은 :doc:`venv <python:tutorial/venv>`를 사용하는 것입니다. 이 도구를 사용하면 각각 고유한 라이브러리 및 패키지 네임스페이스 복사본이 있는 다수의 분리된 Python 환경을 유지할 수 있습니다.