Programming

; develop a program

Framework/Django

[Django] 장고(Django) 서비스 개발 - views.py 파일 분리

Clloud_ 2022. 12. 21. 20:36
반응형

장고에 기능을 계속 추가하다 보면 뷰 파일(views.py)에 함수가 계속 늘어나 불편함을 느낄 수 있다.

(현재 추가된 기능만으로도 뷰 파일이 매우 방대해졌다)

 

view 파일에 함수가 많아지면 관리하기 힘들어지기 때문에 개선할 수 있는 두 가지 방법이 있다.

결론적으로 두 번째 방법을 사용할 것이지만 두 번째 방법을 진행하기 위해서는 첫 번째 방법을 적용한 후에 가능하다.

 

이번 포스팅에서는 장고를 사용하여 게시판 서비스 개발에 필요한 views.py 파일 분리에 대하여 공부를 해보고자 한다.

 


첫 번째 방법

첫 번째 방법은 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 하여 사용하던 기존의 파이썬 프로그램을 모두 수정해야 하는 불편함은 있지만 명확해지는 장점이 있다. 

 


 

반응형