본문 바로가기
Research/Django

[Django] 점프 투 장고 튜토리얼 - 3-11 views.py 파일 분리

by RIEM 2021. 11. 25.

Django 점프 투 장고 정리

작성일 : 2021-11-25

문서버전 : 1.0 

개요

이 문서는 점프 투 장고 사이트의 장고 튜토리얼 학습 내용을 정리한 내용입니다.

레퍼런스

점프 투 장고 https://wikidocs.net/72242

3-11 views.py 파일 분리

장고 프로젝트가 점점 커지게되면 views.py의 함수들이 많아져서 프로젝트의 복잡도가 증가한다. Views파일에 함수가 많아지면 관리가 어렵기 때문에 개선이 필요하다. 이를 위해 개선책 2가지를 알아보자. 참고로 두 번째 개선책을 적용하기 위해선 첫 번째 개선책을 적용해야 하므로, 첫 번째 개선책부터 차례대로 적용해보자.

 

첫 번째 개선책

views.py 파일을 여러 파일로 분리하는 방법이다. 나머지는 수정하지 않아도 되기 때문에 심플하다.


> 우선 ../mysite/pybo/views 디렉터리를 생성해주자.

(mysite) c:\projects\mysite\pybo>mkdir views

 

Views.py파일에 정의한 함수들을 기능별로 분리해서 views 디렉터리에 다음과 같은 파일명으로 저장하자.

 

파일명 기능 함수
base_views.py 기본 관리 Index, detail
question_views.py 질문 관리 Question_create, question_modify, question_delete
answer_views.py 답변 관리 Answer_create, answer_modify, answer_delete
comment_views.py 댓글 관리 Comment_create_question, …, comment_delete_answer, … (총 6개)



Base_views.py

> ../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 구문의 경우, from .models import Question와 같이 같은 디렉터리에 위치한 models.py 모듈을 불러내는 것이 아니라 상위 디렉터리에 있는 파일을 임포트 해야하기 때문에 from ..models import Question과 같이 임포트 해준다. 부모 디렉터리의 모듈을 임포트 해야 한다. 

 

Question_views.py

> ../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과 같이 재지정해주자. 

 

Answer_views.py

> ../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):
    (... 생략 ...)

 

Comment_views.py

> ../mysite/pybo/views/comment_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 CommentForm
from ..models import Question, Answer, Comment


@login_required(login_url='common:login')
def comment_create_question(request, question_id):
    (... 생략 ...)


@login_required(login_url='common:login')
def comment_modify_question(request, comment_id):
    (... 생략 ...)


@login_required(login_url='common:login')
def comment_delete_question(request, comment_id):
    (... 생략 ...)


@login_required(login_url='common:login')
def comment_create_answer(request, answer_id):
    (... 생략 ...)


@login_required(login_url='common:login')
def comment_modify_answer(request, comment_id):
    (... 생략 ...)


@login_required(login_url='common:login')
def comment_delete_answer(request, comment_id):
    (... 생략 ...)

 

__init__.py

> ../mysite/pybo/views/__init__.py

View 디렉터리에 __init__.py 파일을 생성해주자.

 
from .base_views import *
from .question_views import *
from .answer_views import *
from .comment_views import *

Views 디렉터리의 __init__.py 파일는 views 디렉터리에 있는 base_views.py 등 모든 views 함수들을 import해준다. 따라서 pybo/urls/py 와 같은 다른 모듈에서 views 모듈의 함수 사용하는 부분을 수정할 필요가 없다. 

pybo/views.py 삭제

파일 작성이 끝났으니 pybo/views.py 파일을 삭제하자. 정리 후 views 디렉터리의 모습은 다음과 같다.

Views가 분리된 이후에도 정상적으로 잘 작동된다.

 

두 번째 개선책

첫 번째 방법에 단점이 하나 있다. 장고는 디버깅 시 urls.py파일에서 URL에 매핑된 함수를 찾는 것으로 시작한다. 하지만 첫 번째 방법 사용하면 urls.py파일에 매핑된 함수 명만 알고 어떤 뷰의 파일인지는 알 수 없다는 문제가 생긴다. 특히 여러명이 동시에 장고 프로젝트를 진행하게 될 경우 혼선이 더욱 발생한다.

 

이를 개선하기 위해 views 디렉터리의 __init__.py 파일을 제거하고, pybo/urls.py에 views.index 대신 base_views.index 와 같이 전체 경로를 기재해주는 방법을 사용할 수 있다.

views/__init__.py 파일 제거

(mysite) C:\projects\mysite\pybo\views>del __init__.py

 

pybo/urls.py

>../mysite/pybo/urls.py

Urls.py 파일을 아래와 같이 수정해주자.

 
from django.urls import path

from .views import base_views, question_views, answer_views, comment_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'),

    # comment_views.py
    path('comment/create/question/<int:question_id>/',
        comment_views.comment_create_question, name='comment_create_question'),
    path('comment/modify/question/<int:comment_id>/',
        comment_views.comment_modify_question, name='comment_modify_question'),
    path('comment/delete/question/<int:comment_id>/',
        comment_views.comment_delete_question, name='comment_delete_question'),
    path('comment/create/answer/<int:answer_id>/',
        comment_views.comment_create_answer, name='comment_create_answer'),
    path('comment/modify/answer/<int:comment_id>/',
        comment_views.comment_modify_answer, name='comment_modify_answer'),
    path('comment/delete/answer/<int:comment_id>/',
        comment_views.comment_delete_answer, name='comment_delete_answer'),
]

 

URL 매핑 시 views.index를 base_views.index와 같이 해당 모듈명이 표시되도록 바꾸었다. 모듈명이 있어 어떤 뷰 파일의 함수인지 명확해졌다.

 

config/urls.py

config/urls.py의 index에 해당하는 URL 매핑도 views에서 base_views로 수정해주자.

> ../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하여 사용하던 기존 파이썬 프로그램을 모두 수정해야 한다는 수고로움은 있지만 프로그램의 혼선을 방지할 수 있다는 장점이 있다.

 

 

댓글