첫 Django 패치 작성하기

개요

커뮤니티에 보답하고 싶은가요? 고치고 싶은 버그가 있거나, 추가하고 싶은 기능이 있을지도 모릅니다.

Django에 기여하는 것이야말로 여러분의 문제를 해결하는 최선의 방법입니다. 처음에는 부담스러울 수도 있지만 문서, 도구 및 커뮤니티를 이용하면 쉽게 이용할 수 있습니다. 모든 과정을 안내해 드릴 것이므로,예제를 통해 배울 수 있습니다.

이 튜토리얼은 누구를 위한 것인가요?

더 보기

코드 기여에 대한 세부 참조를 보려면 :doc:’/internals/committing/writing-code/index’ 문서를 참조하십시오.

이 튜토리얼을 진행하기 위해서는, Django에 대한 기본적인 이해가 필요합니다. 첫번째 Django 앱 작성해보기 를 무난하게 따라할 정도면 됩니다. 또한, Python에 대한 적당한 이해도 필요합니다만, 그렇지 않다면 초보 Python 프로그래머를 위한 훌륭한 (무료 ) 온라인 도서 `Dive Into Python`__ 을 권장합니다.

버전 관리 시스템과 Trac에 대해 잘 모르는 분은 이 튜토리얼과 튜토리얼에 포함된 링크를 통해 충분한 정보를 찾을 수 있을 것입니다. 하지만, 장고에 계속 공헌하고자 한다면 이러한 다른 도구들에 대하여 더 읽어두는 것도 좋을 것입니다.

하지만 대부분의 경우, 이 튜토리얼은 폭넓은 독자에게 사용이 될 수 있도록 최대한 설명하려고 합니다.

도움을 받을 수 있는 방법

이 튜토리얼을 진행하다가 어려움이 있다면 `Django Forum`_의 |django developers|에 메시지를 보내거나, irc.libera.chat___에 있는 ‘#django-dev on irc.libera-chat____를 통해 도움을 줄 수 있는 다른 장고 사용자와 이야기하기하십시오.

이 튜토리얼이 다루는 내용은 무엇입니까?

여기서는 여러분이 장고에 대한 패치를 처음 제출하는 과정을 다룹니다. 이 튜토리얼을 마치면, 여러분은 기본적인 관련 도구와 프로세스를 모두 이해하게 될 것입니다. 좀더 구체적으로는 다음 내용을 다룹니다.

  • GIT 설치
  • Django의 개발 버전 사본 다운로드
  • Django의 테스트 스위트를 실행.
  • 패치에 대한 테스트를 작성.
  • 패치 코드를 작성.
  • 패치를 테스트.
  • pull request 보내기.
  • 더 많은 정보를 찾을 수 있는 곳.

한번 튜토리얼을 마쳤다면, Django 문서의 기여하기를 통해 나머지를 볼 수 있습니다. 다양한 정보들이 있으며, 특히 Django 의 정규 기여자가 되고 싶다면 반드시 봐야 합니다. 궁금하신 점이 있다면 답을 얻으실 수 있을 것입니다.

파이썬 3.x 버전이 필요합니다.

Django 현재의 버전은 파이썬 2.7 을 지원하지 않습니다. 파이썬 다운로드 페이지 또는 자신의 운영체제의 패키지 관리자로부터 파이썬 3을 받을 수 있습니다.

윈도우 운영체제를 사용하는 경우

See 파이썬 설치 on Windows docs for additional guidance.

행동 지침

당신은 기여자로서, 개방적이고 포괄적인 Django 커뮤니티를 유지하도록 도움을 줄 수 있습니다. 행동 강령 을 읽고 숙지해주세요.

GIT 설치

이 튜토리얼에서와 같이, 현재 개발 버전의 Django를 다운로드하고 수정하여 패치 파일을 생성하기 위해서는 Git을 설치해야 합니다.

Git 이 설치되었는지 확인해보기 위해, 커맨드라인에서 git 라고 입력해보세요. 만약 그런 명령을 찾을 수 없다는 메세지가 나오면 Git 이 설치되지 않았다는 의미입니다. `Git's download page`__ 를 참조하세요.

Git을 사용하는 것이 익숙하지 않다면, (우선 설치가 완료되면) 커맨드라인 상에서 git help를 입력함으로써 명령어에 대한 자세한 정보를 확인할 수 있습니다.

Django 개발 버전의 사본을 얻기

Django에 기여하기 위한 첫걸음은 소스 코드를 내려받는 것입니다. 먼저, 깃허브에서 Django를 포크하세요. 그 다음에, 명령행에서 cd 명령을 통해 Django 소스를 내려받을 디렉토리로 이동하세요.

다음 명령을 통해 Django 소스코드 저장소를 다운로드하십시오.

$ git clone https://github.com/YourGitHubName/django.git
...\> git clone https://github.com/YourGitHubName/django.git

인터넷이 느린가요 (대역폭이 낮나요) ?

git clone 명령어 뒤에 --depth 1 인자를 추가하면 Django의 이전 수정 이력을 무시하고 최신 수정 이력만 남은 소스코드를 다운로드 받을 수 있습니다. 이로써 다운로드 받아야할 데이터 용량이 250MB 정도에서 70MB 정도로 줄어들게 된답니다.

Django의 로컬 사본을 갖게 되었으므로, 여느 패키지와 마찬가지로 pip를 사용해 설치할 수 있습니다. 가장 편리한 방법은 Python에 내장된 가상 환경 기능을 사용하는 것으로, 각 프로젝트를 위해 설치한 패키지들을 별도의 디렉토리에 둠으로써 서로 간섭이 일어나지 않도록 할 수 있습니다.

모든 가상 환경을 홈 디렉토리의 .virtualenvs/ 같은 곳에 모아두는 것이 좋습니다.

다음 명령을 실행해 새로운 가상 환경을 생성합니다.

$ python3 -m venv ~/.virtualenvs/djangodev
...\> py -m venv %HOMEPATH%\.virtualenvs\djangodev

경로는 당신의 컴퓨터에서 새로운 환경이 저장될 위치를 의미합니다.

가상 환경을 활성화함으로써 구성을 마무리합니다.

$ source ~/.virtualenvs/djangodev/bin/activate

만약 source 명령을 사용할 수 없다면, 대신 마침표(.)를 사용해 보십시오.

$ . ~/.virtualenvs/djangodev/bin/activate

새로운 터미널 창을 열 때마다 가상 환경을 활성화해야 합니다.

윈도우 운영체제를 사용하는 경우

Windows에서 가상 환경을 활성화하려면 다음 명령을 사용합니다.

...\> %HOMEPATH%\.virtualenvs\djangodev\Scripts\activate.bat

현재 활성화된 가상 환경의 이름이 명령행에 표시되므로 현재 사용하는 것이 무엇인지 알 수 있습니다. 이러한 이름이 표시되는 동안 pip로 설치한 것은 해당 가상 환경 내에 설치되어, 다른 환경 및 시스템 패키지와 격리됩니다.

앞서 복제한 Django 사본을 설치합니다.

$ python -m pip install -e /path/to/your/local/clone/django/
...\> py -m pip install -e \path\to\your\local\clone\django\

현재 설치된 Django는 로컬 사본을 가리킵니다. 이에 대한 모든 변경을 즉시 확인할 수 있으며, 이러한 구조는 첫 번째 패치를 작성할 때 큰 도움이 될 것입니다.

로컬 디스크에 있는 Django 복사본으로부터 프로젝트 생성하기

It may be helpful to test your local changes with a Django project. First you have to create a new virtual environment, install the previously cloned local copy of Django in editable mode, and create a new Django project outside of your local copy of Django. You will immediately see any changes you make to Django in your new project, which is of great help when writing your first patch, especially if testing any changes to the UI.

You can follow the tutorial for help in creating a Django project.

Django의 테스트 스위트를 처음으로 실행하기

Django에 기여할 때 당신의 코드 변경이 Django의 다른 영역에 버그가 발생하지 않도록 하는 것이 매우 중요합니다. 변경한 후에도 Django가 여전히 작동하는지 확인하는 한 가지 방법은 Django의 test suite를 실행하는 것입니다. 모든 테스트가 여전히 통과한다면, Django의 다른 부분이 망가지지 않았다고 확신할 수 있습니다. 아직 한 번도 Django의 test suite를 실행해 본 적이 없다면 출력물에 익숙해지기 위해 미리 한 번 실행해보는 것이 좋습니다.

test suite를 실행하기 전, cd tests 명령어를 사용하여 Django의 tests/ 디렉토리에 들어갑니다. 그리고 다음을 실행하여 테스트 종속성을 설치하세요:

$ python -m pip install -r requirements/py3.txt
...\> py -m pip install -r requirements\py3.txt

설치 중 오류가 발생했다면, 시스템이 하나 이상의 Python 패키지에 대한 의존성을 해결하지 못한 것일 수 있습니다. 설치에 실패한 패키지의 문서를 참조하거나 오류 메시지를 웹에서 검색하십시오.

이제 테스트 스위트를 실행할 준비가되었습니다. GNU/Linux, macOS, 그외의 Unix 구현체를 사용한다면 다음을 실행합니다.

$ ./runtests.py
...\> runtests.py 

Now sit back and relax. Django’s entire test suite has thousands of tests, and it takes at least a few minutes to run, depending on the speed of your computer.

Django 테스트 스위트가 실행되는 동안 각각의 테스트가 완료되는 상태를 나타내는 문자들이 흘러가는 것을 볼 수 있습니다. E는 테스트 중에 오류가 발생했음을 가리키며, F는 테스트의 단정문이 실패한 것을 가리킵니다. 둘 다 테스트 실패로 간주됩니다. x는 예견된 실패를, s는 테스트를 건너뛴 것을 가리킵니다. 테스트가 통과하면 점이 찍힙니다.

건너뛴 테스트는 보통 테스트를 수행하기 위해 필요한 외부 라이브러리가 없는 경우 발생합니다. 모든 테스트를 실행합니다.를 참조하여, 변경과 관련한 모든 테스트를 수행하기 위한 의존성을 확인하고 이를 설치하십시오(이 튜토리얼에서는 필요하지 않습니다). 특정한 데이터베이스 백엔드를 필요로 하는 테스트의 경우, 해당 데이터베이스 백엔드를 사용하지 않으면 자동으로 테스트를 건너뜁니다. SQLite는 기본 데이터베이스 백엔드입니다. 다른 백엔드를 테스트하고 싶다면 다른 ‘’설정’’ 모듈을 사용합니다.를 참조하세요.

검사가 완료되면, 테스트 스위트 통과했거나 실패했다는 메시지를 보게 될 것입니다. 아직 Django의 코드를 전혀 변경하지 않았으므로, 전체 테스트를 반드시 통과해야 합니다. 실패하였으나 오류가 발생하였다면 이전의 모든 단계를 올바로 따라서 문제를 해결해야 합니다. 장치 테스트를 실행에서 자세한 내용을 확인하세요.

최신 Django “main” branch가 항상 안정적인 것은 아닙니다. “main”에 개발할 때, `Django's continuous integration builds`__ 를 확인하여 실패들이 당신의 머신과 관련이 있는지, 혹은 Django의 공식 빌드에도 존재하는지 확인할 수 있습니다. 특정 빌드를 클릭하면 어느 Python 버전과 데이터베이스 백엔드에서 오류가 일어나는지 보여주는 “Configuration Matrix”를 볼 수 있습니다.

참고

For this tutorial and the ticket we’re working on, testing against SQLite is sufficient, however, it’s possible (and sometimes necessary) to run the tests using a different database. When making UI changes, you will need to run the Selenium tests.

기능 추가하기

이 튜토리얼에서 우리는 사례 연구를 위해 “가짜 티켓”을 처리합니다. 내용은 다음과 같습니다.

티켓 #99999 – 토스트 만들기

Django는 ‘toast’`를 반환하는 함수 django.shortcuts.make_toast()를 제공해야 한다.

이 기능 및 관련된 테스트를 구현해봅시다.

패치 용 branch 만들기

변경하기 전에 티켓의 새 branch를 생성합니다.

$ git checkout -b ticket_99999
...\> git checkout -b ticket_99999

branch 이름을 원하는 대로 정할 수 있으며, “ticket_99999”는 예시입니다. 이 branch에 대한 모든 변경은 특정한 티켓에만 적용되며 앞서 복제한 코드의 메인 사본에는 영향을 끼치지 않습니다.

티켓에 대한 테스트를 작성하기

대부분의 경우에, Django에 대한 패치를 접수할 때에는 테스트를 포함합니다. 버그 수정 패치의 경우, 이것은 그 버그가 나중에 Django에서 다시 발생하지 않도록 회귀 테스트를 작성하는 것을 의미합니다. 회귀 테스트는 버그가 존재하는 동안 실패하다가 일단 버그가 수정되면 통과하도록 작성하여야 합니다. 새로운 기능을 포함하는 패치의 경우 새로운 기능이 올바르게 작동하는지 확인하는 테스트를 포함해야 합니다. 그러한 테스트들은 새로운 기능이 존재하지 않는 경우에는 실패하고, 구현이 되면 통과합니다.

이 작업을 수행하는 좋은 방법은 코드를 변경하기 전에, 먼저 새로운 테스트부터 작성하는 것입니다. 이러한 개발 스타일은 `test-driven development`__이라고 불리우며, 낱개의 패치에서부터 전체 프로젝트에 이르기까지 적용이 가능합니다. 테스트를 작성한 후에는 (당신이 버그를 수정하거나 아직이 기능을 추가하지 않았기 때문에) 그것들이 실제로 실패하는지 확인하기 위해 실행시켜보도록 합니다. 새 테스트가 실패하지 않을 경우, 테스트가 실패하도록 수정해야합니다. 버그가 있든없든 통과하는 회귀 테스트라면 다시 발생하는 버그를 방지하는 데에 그다지 도움이 되지 않습니다.

이제 우리 예제를 살펴보도록 하겠습니다.

티켓 #99999에 대한 테스트 작성하기

이 티켓을 해결하기 위해 우리는 django.shortcuts 모듈에 make_toast() 기능을 추가할 것입니다. 먼저 함수를 사용하려는 테스트를 작성하여 출력이 올바르게 보이는지 확인하겠습니다.

Django의 tests/shortcuts/ 폴더로 가서 새 파일 test_make_toast.py를 생성합니다. 다음의 코드를 추가합니다.

from django.shortcuts import make_toast
from django.test import SimpleTestCase


class MakeToastTests(SimpleTestCase):
    def test_make_toast(self):
        self.assertEqual(make_toast(), "toast")

이 테스트는 make_toast()'toast'를 반환하는지 검사합니다.

하지만 테스팅이 어려워보입니다…

이전에 테스트를 한번도 다뤄보지 않았다면, 처음에는 작성하기에 까다로울 수도 있습니다. 다행히도, 테스트는 컴퓨터 프로그래밍에서 매우 중요한 주제이기 때문에, 많은 정보를 얻을 수 있습니다.

  • 첫 Django 테스트 작성하기의 좋은 예제는 Writing and running tests에 있는 문서에서 찾을 수 있습니다.
  • Dive Into Python (초보 파이썬 개발자를 위한 무료 온라인북)에 훌륭한 `introduction to Unit Testing`__이 있습니다.
  • 그것들을 읽어본 후에, 좀 더 음미해보고 싶다면, Python unittest 문서를 읽어보기 바랍니다.

새 테스트를 수행하기

django.shortcuts를 아직 수정하지 않았기 때문에 테스트가 실패할 것입니다. 실제로 무슨 일이 일어나는지 알기 위해 모든 테스트를 shortcuts 폴더에서 수행합시다. Django tests/ 디렉토리로 cd하여 다음을 실행합니다.

$ ./runtests.py shortcuts
...\> runtests.py shortcuts

테스트가 올바르게 실행되면, 이 오류와 함께 우리가 추가한 테스트 방법에 해당하는 하나의 실패가 표시됩니다.

ImportError: cannot import name 'make_toast' from 'django.shortcuts'

모든 테스트가 통과하면 위에서 살펴본 새로운 테스트를 올바른 폴더와 파일명으로 추가합니다.

티켓에 대한 코드를 작성하기

다음으로는 make_toast() 함수를 추가합니다.

django/ 폴더로 이동해 shortcuts.py 파일을 엽니다. 맨 아래에 다음을 추가합니다.

def make_toast():
    return "toast"

이제 우리는 앞에서 작성한 테스트가 통과하는 것을 확인함으로써, 추가한 코드가 올바로 동작함을 확신할 수 있습니다. Django tests/ 디렉토리로 다시 이동해 다음을 실행합니다.

$ ./runtests.py shortcuts
...\> runtests.py shortcuts

모든 테스트가 통과할 것입니다. 만약 그렇지 않다면, 함수를 올바른 파일에 올바로 추가했는지 확인하세요.

Django의 테스트 스위트를 두 번째로 실행하기

패치와 테스트가 올바르게 작동하는 것을 확인했으면, 전체 Django test suite를 실행하여 변경 사항이 Django의 다른 영역에 버그가 발생하지 않았는지 확인하는 것이 좋습니다. 전체 test suite를 통과했다고 해서 버그가 없는 것을 확신할 수는 없지만, 모르고 지나쳤을 수도 있는 많은 버그와 잘못을 찾아내는 데 도움이 됩니다.

Django 테스트 스위트 전체를 실행하려면, Django tests/ 디렉토리로 cd하여 다음과 같이 실행합니다:

$ ./runtests.py
...\> runtests.py 

문서 작성하기

이것은 새로운 기능이므로 문서화해야합니다. docs/topics/http/shortcuts.txt 파일을 열고 파일 끝에 다음을 추가하십시오.

``make_toast()``
================

.. function:: make_toast()

.. versionadded:: 2.2

Returns ``'toast'``.

이 새로운 기능은 곧 출시될 예정이므로 Django의 다음 버전에 대한 릴리즈 노트에도 추가해야 합니다. 작성 당시 ``2.2.txt``인 ``docs/releases/``의 최신 버전의 릴리즈 노트를 여십시오. “기본 기능” 헤더를 노트에 추가하십시오.

:mod:`django.shortcuts`
~~~~~~~~~~~~~~~~~~~~~~~

* The new :func:`django.shortcuts.make_toast` function returns ``'toast'``.

versionadded에 대한 설명을 포함하여, 문서 작성에 대한 자세한 내용은 문서 작성하기을 참조하시기 바랍니다. 그 페이지에는 문서의 사본을 로컬에서 빌드하여, 생성되는 HTML을 미리 살펴볼 수 있도록 하는 방법도 설명하고 있습니다.

변경사항 미리보기

우리의 패치의 모든 변경 사항을 훑어볼 시간입니다. 커밋 준비된 모든 변경사항을 스테이지합니다.

$ git add --all
...\> git add --all

그 다음으로 Django의 현재 사본(변경 사항을 포함)과 튜토리얼을 시작할 때 처음 체크아웃한 리비전 사이의 차이를 표시합니다.

$ git diff --cached
...\> git diff --cached

위 아래로 움직이려면 화살표 키를 사용하세요.

diff --git a/django/shortcuts.py b/django/shortcuts.py
index 7ab1df0e9d..8dde9e28d9 100644
--- a/django/shortcuts.py
+++ b/django/shortcuts.py
@@ -156,3 +156,7 @@ def resolve_url(to, *args, **kwargs):

     # Finally, fall back and assume it's a URL
     return to
+
+
+def make_toast():
+    return 'toast'
diff --git a/docs/releases/2.2.txt b/docs/releases/2.2.txt
index 7d85d30c4a..81518187b3 100644
--- a/docs/releases/2.2.txt
+++ b/docs/releases/2.2.txt
@@ -40,6 +40,11 @@ database constraints. Constraints are added to models using the
 Minor features
 --------------

+:mod:`django.shortcuts`
+~~~~~~~~~~~~~~~~~~~~~~~
+
+* The new :func:`django.shortcuts.make_toast` function returns ``'toast'``.
+
 :mod:`django.contrib.admin`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt
index 7b3a3a2c00..711bf6bb6d 100644
--- a/docs/topics/http/shortcuts.txt
+++ b/docs/topics/http/shortcuts.txt
@@ -271,3 +271,12 @@ This example is equivalent to::
         my_objects = list(MyModel.objects.filter(published=True))
         if not my_objects:
             raise Http404("No MyModel matches the given query.")
+
+``make_toast()``
+================
+
+.. function:: make_toast()
+
+.. versionadded:: 2.2
+
+Returns ``'toast'``.
diff --git a/tests/shortcuts/test_make_toast.py b/tests/shortcuts/test_make_toast.py
new file mode 100644
index 0000000000..6f4c627b6e
--- /dev/null
+++ b/tests/shortcuts/test_make_toast.py
@@ -0,0 +1,7 @@
+from django.shortcuts import make_toast
+from django.test import SimpleTestCase
+
+
+class MakeToastTests(SimpleTestCase):
+    def test_make_toast(self):
+        self.assertEqual(make_toast(), 'toast')

패치 미리보기가 끝나면 q 키를 눌러 명령행으로 돌아갑니다. 패치의 내용이 괜찮아 보이면 변경사항을 커밋해야 합니다.

패치 변경사항 적용하기

변경사항을 적용하려면:

$ git commit
...\> git commit

그러면 커밋 메시지를 입력하기 위한 텍스트 편집기가 열립니다. 커밋 메시지 가이드라인에 따라 다음과 같은 메시지를 작성하십시오.

Fixed #99999 -- Added a shortcut function to make toast.

commit 푸시 및 pull request 만들기

패치를 커밋한 다음, 깃허브에서 포크한 저장소에 보냅니다(“ticket_99999”를 당신의 브랜치 이름에 맞게 바꾸세요).

$ git push origin ticket_99999
...\> git push origin ticket_99999

Django GitHub 페이지를 방문하여 pull 요청을 할 수 있습니다. “최근 푸시 된 브랜치” 아래에 브랜치가 보일 것입니다. 옆의 “Compare & pull request”를 클릭하십시오.

이 자습서에서는 하지 말고, 패치의 미리보기를 표시하는 다음 페이지에서 “pull request 만들기”를 클릭하십시오.

다음 단계

축하합니다. Django에 풀 리퀘스트를 하는 법을 배웠습니다! 필요한 고급 기술에 대한 자세한 내용은 Git 및 GitHub와 함께 작업에 있습니다.

이제 Django의 코드베이스를 개선하여 이러한 기술을 유용하게 사용할 수 있습니다.

새로 오신 기여자분들을 위한 추가 정보

Django를 위한 패치를 작성하기 전에, 한번 꼭 보셔야 할 정보들이 있습니다.

  • Django 문서 중, 티켓 생성과 패치 제출 문서를 반드시 읽어보십시요. 이 문서는 Trac 사용 예절과, 직접 티켓을 생성하는 방법, 패치 작성 시 지켜야 할 코딩 스타일과 다른 중요한 것들을 자세히 설명합니다.
  • 기여가 처음이신 분들은 첫 기여자를 위한 문서 를 읽어주십시요. Django 를 도와주시려는 분들을 위한 좋은 조언들이 가득합니다.
  • 기여에 대한 정보가 이것으로 충분하지 않으시면, Django 문서의 기여 항목 의 나머지를 흝어보세요. 엄청나게 많은 정보들이 있으며, 궁금하신 점들은 여기서 제일 먼저 찾으셔야 합니다.

첫 번째 진짜 티켓을 찾기

여기까지 흝어 보셨다면, 이제 직접 패치를 작성해볼 티켓을 찾아봅시다. “easy pickings” 제약이 걸린 티켓들을 주의깊게 살펴 봅시다. 이 티켓들은 처리하기 쉬운편이라, 초보 기여자에게 적당합니다. 일단 Django 에 기여하는 과정에 익숙해지면, 조금 더 복잡하고 어려운 티켓에 도전할 수 있습니다.

지금 당장 시작해보고 싶다면(아무도 비난하지 않을 겁니다!), `easy tickets that need patches`__ 목록과 `easy tickets that have patches which need improvement`__ 목록을 살펴보십시오. 테스트를 작성하는데에 익숙하다면, `easy tickets that need tests`__ 도 참고할 수 있습니다. Django 문서 claiming tickets and submitting patches 링크에 언급된 티켓 생성에 대한 지침을 잊지 마십시오.

pull request를 만든 후 다음은 무엇입니까?

티켓에 패치가 있는 경우 두 번째 눈으로 검토해야 합니다. pull 요청을 제출한 후 티켓에 “패치가 있음”, “테스트가 필요 없음” 등의 플래그를 설정하여 티켓 메타데이터를 업데이트하여 다른 사람들이 검토할 수 있도록 합니다. 기여한다고 해서 항상 패치를 처음부터 작성하는 것은 아닙니다. 기존 패치를 검토하는 것도 매우 도움이 됩니다. 자세한 내용은 티켓 분류를 참조하십시오.

Back to Top