장고에 기능을 계속 추가하다 보면 뷰 파일(views.py)에 함수가 계속 늘어나 불편함을 느낄 수 있다.
(현재 추가된 기능만으로도 뷰 파일이 매우 방대해졌다)
view 파일에 함수가 많아지면 관리하기 힘들어지기 때문에 개선할 수 있는 두 가지 방법이 있다.
결론적으로 두 번째 방법을 사용할 것이지만 두 번째 방법을 진행하기 위해서는 첫 번째 방법을 적용한 후에 가능하다.
첫 번째 방법
첫 번째 방법은 views.py 파일만 여러 파일로 분리하고 나머지는 고치지 않아도 되는 변화가 적은 방법이다.
먼저 projects\mysite\pybo\views 디렉터리를 다음과 같이 생성한다.
(mysite) c:\projects\mysite\pybo>mkdir views
파이참 pybo 디렉터리에서 오른쪽 마우스를 클릭한 다음 [New → Directory]로 생성해도 된다.
그리고 views.py 파일에 정의한 함수를 기능별로 분리하여 views 디렉터리에 다음의 파일로 저장한다.
우선 다음 표를 보고 views 디렉터리에 빈 파일을 만들어 놓아야 한다.
파일명 | 기능 | 함수 |
base_views.py | 기본관리 | index, detail |
question_views.py | 질문관리 | question_create, question_modify, question_delete |
answer_views.py | 답변관리 | answer_create, answer_modify, answer_delete |
base_views.py
base_views.py 파일을 다음과 같이 작성한다.
함수의 기능을 바꾸거나 하지 않았으므로 함수 내용은 모두 생략했다.
[파일명: projects\mysite\pybo\views\base_views.py]
from django.core.paginator import Paginator
from django.shortcuts import render, get_object_or_404
from ..models import Question
def index(request):
(... 생략 ...)
def detail(request, question_id):
(... 생략 ...)
pybo/views.py 파일에 있던 index 함수와 detail 함수를 내용의 변경 없이 그대로 복사하면 된다.
하지만 import 문은 조금 바꾸어야 한다.
기존 pybo/views.py에서는 from .models import Question 처럼 같은 디렉터리에 있는 models.py 모듈을 import 했지만 지금은 views 디렉터리 하위에 base_views.py 파일이 위치하므로 from ..models import Question 처럼 부모디렉터리의 models.py 모듈을 import 해야 한다.
파이참에서 import문 정리하기
파이참을 사용할 경우 pybo/views.py의 모든 import문을 그대로 Copy 한 후 Ctrl+Alt+o를 입력하면 쉽게 import문들을 정리할 수 있다.
Ctrl+Alt+o에서 o는 알파벳 o이다.
question_views.py
question_views.py 파일은 다음과 같이 작성한다.
[파일명: projects\mysite\pybo\views\question_views.py]
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from ..forms import QuestionForm
from ..models import Question
@login_required(login_url='common:login')
def question_create(request):
(... 생략 ...)
@login_required(login_url='common:login')
def question_modify(request, question_id):
(... 생략 ...)
@login_required(login_url='common:login')
def question_delete(request, question_id):
(... 생략 ...)
models.py와 마찬가지로 forms.py도 부모 디렉터리에 있으므로 from ..forms import QuestionForm 와 같이 import문을 변경해 주어야 한다.
answer_views.py
answer_views.py 는 다음과 같이 작성한다.
[파일명: projects\mysite\pybo\views\answer_views.py]
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from ..forms import AnswerForm
from ..models import Question, Answer
@login_required(login_url='common:login')
def answer_create(request, question_id):
(... 생략 ...)
@login_required(login_url='common:login')
def answer_modify(request, answer_id):
(... 생략 ...)
@login_required(login_url='common:login')
def answer_delete(request, answer_id):
(... 생략 ...)
__init__.py
views 디렉터리에 __init__.py 파일을 다음과 같이 작성한다.
[파일명: projects\mysite\pybo\views\__init__.py]
from .base_views import *
from .question_views import *
from .answer_views import *
views 디렉터리의 __init__.py 파일에서 views 디렉터리에 있는 base_views.py 등의 모든 뷰 파일의 함수를 import 했기 때문에 pybo/urls.py와 같은 다른 모듈에서 views 모듈의 함수를 사용하는 부분을 수정할 필요가 없다.
pybo/views.py 삭제
파일 작성이 끝났으니 pybo/views.py 파일은 삭제한다.
정리 후 views 디렉터리의 모습은 다음과 같다.
이렇게 수정하고 테스트해 보면 아무런 이상 없이 잘 동작하는 것을 확인할 수 있다.
두 번째 방법
첫 번째 방법에는 단점이 있다.
장고는 디버깅 시 보통 urls.py 파일에서 URL에 매핑된 함수를 찾는 것으로 시작한다.
하지만 첫 번째 방법을 사용하면 urls.py 파일에 매핑된 함수명은 알 수 있지만 어떤 뷰 파일의 함수인지는 알 수가 없다.
이는 views 디렉터리의 모든 뷰 파일을 찾아봐야 하는 불편함을 초래하게 한다.
이러한 이유로 혼자가 아닌 여러 명이 함께 하는 프로젝트라면 첫 번째 방법은 절대로 추천하지 않는다.
두 번째 방법은 views 디렉터리의 __init__.py 파일을 제거하고 pybo/urls.py에서 views.index 대신 base_views.index 와 같이 전체 경로를 써주는 방법이다.
views/__init__.py 파일 제거
우선 문제가 되는 views 디렉터리의 __init__.py 파일을 제거하자.
(mysite) C:\projects\mysite\pybo\views>rm __init__.py
pybo/urls.py
pybo/urls.py 파일을 다음과 같이 수정한다.
[파일명: projects\mysite\pybo\urls.py]
from django.urls import path
from .views import base_views, question_views, answer_views
app_name = 'pybo'
urlpatterns = [
# base_views.py
path('',
base_views.index, name='index'),
path('<int:question_id>/',
base_views.detail, name='detail'),
# question_views.py
path('question/create/',
question_views.question_create, name='question_create'),
path('question/modify/<int:question_id>/',
question_views.question_modify, name='question_modify'),
path('question/delete/<int:question_id>/',
question_views.question_delete, name='question_delete'),
# answer_views.py
path('answer/create/<int:question_id>/',
answer_views.answer_create, name='answer_create'),
path('answer/modify/<int:answer_id>/',
answer_views.answer_modify, name='answer_modify'),
path('answer/delete/<int:answer_id>/',
answer_views.answer_delete, name='answer_delete'),
]
URL 매핑 시 views.index 를 base_views.index 와 같이 해당 모듈명이 표시되도록 바꾸었다.
모듈명이 있기 때문에 이제 누가 보더라도 어떤 뷰 파일의 함수인지 명확하게 인지할 수 있다.
config/urls.py
그리고 config/urls.py의 index에 해당되는 URL 매핑도 views 대신 base_views를 사용하도록 다음처럼 수정해야 한다.
[파일명: projects\mysite\config\urls.py]
from django.contrib import admin
from django.urls import include, path
from pybo.views import base_views
urlpatterns = [
path('pybo/', include('pybo.urls')),
path('common/', include('common.urls')),
path('admin/', admin.site.urls),
path('', base_views.index, name='index'), # '/' 에 해당되는 path
]
두 번째 방법을 사용할 경우 이미 views.py 모듈을 import 하여 사용하던 기존의 파이썬 프로그램을 모두 수정해야 하는 불편함은 있지만 명확해지는 장점이 있다.
'Framework > Django' 카테고리의 다른 글
[Django] 장고(Django) 서비스 개발 - 앵커(anchor) (2) | 2022.12.23 |
---|---|
[Django] 장고(Django) 서비스 개발 - 추천 (4) | 2022.12.22 |
[Django] 장고(Django) 서비스 개발 - 수정과 삭제 (2) | 2022.12.20 |
[Django] 장고(Django) 서비스 개발 - 글쓴이 표시 (2) | 2022.12.19 |
[Django] 장고(Django) 서비스 개발 - 모델 변경 (2) | 2022.12.18 |