IT/Linux

[Python] django 뷰 파일 분리

액트 2022. 12. 5. 14:29

질문 관련 함수와 답변 관련 함수들이 정의되어 있는 views.py 파일을 다음과 같이 나누고자 합니다.

질문 관련 함수는 question_views.py로 답변 관련 함수는 answer_views.py로 정의합니다.

그리고 기본 정의된 index와 detail 함수는 base_views.py 파일에 정의합니다.

파일명 기능 함수
base_views.py 기본 관리 index.detail
question_views.py 질문 관리 question_create, question_modify, question_delete
answer_views.py 답변 관리 answer_create, answer_modify, answer_delete

먼저 mysite\pybo 하위에 views 디렉터리를 생성합니다.

생성한 views 디렉터리 하위에 base_views.py, question_views.py, answer_views.py 를 생성합니다.

 

1. base_views.py 파일 정의

기존 views.py에 정의 되어 있던 index, detail 함수 구문을 복사 붙혀넣기 합니다. 

다음은 views.py에 있는 모든 import 문을 복사 붙혀넣기 한 다음에 파이참 기능으로 ctrl+alt+o 키를 입력하면 불필요한 import 문은 제거되고 필요한 import 문만 남습니다. 

다만 기존 Question이 정의되었던 models.py  파일의 위치가 views 디렉터리와 동등한 위치에 존재하므로 form ..forms 를 적용하여 models.py 모듈을 import해야 합니다.

from django.core.paginator import Paginator
from django.shortcuts import render, get_object_or_404
from ..forms import Question


def index(request):
    page = request.GET.get('page', '1') # 페이지
    question_list = Question.objects.order_by('-create_date')
    paginator = Paginator(question_list, 10) # 페이지당 10개씩 보여주기
    page_obj = paginator.get_page(page)
    context = {'question_list': page_obj}
    return render(request, 'pybo/question_list.html', context)


def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    context = {'question': question}
    return render(request, 'pybo/question_detail.html', context)

 

2. question_views.py

기존 views.py 에 있는 question 관련 함수(question_create, question_modify, question_delete) 와 import문을 복사 붙혀넣기한 다음에 Alt+Ctrl+O 키를 누릅니다.

정리된 import문에서 아래 구문의 .forms 와 .models 의 경로만 변경해줍니다. 

from .forms import QuestionForm    ===>>  from ..forms import QuestionForm
from .models import Question       ===>>  from ..models import Question
# Create your views here.

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):
    if request.method == 'POST':
        form = QuestionForm(request.POST)
        if form.is_valid():
            question = form.save(commit=False)
            question.author = request.user #author 속성에 로그인 계정 저장
            question.create_date = timezone.now()
            question.save()
            return redirect('pybo:index')
    else:
        form = QuestionForm()
    context = {'form': form}
    return render(request, 'pybo/question_form.html', context)


@login_required(login_url='common:login')
def question_modify(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    if request.user != question.author:
        messages.error(request, '수정 권한이 없습니다')
        return redirect('pybo:detail', question_id=question.id)
    if request.method == "POST":
        form = QuestionForm(request.POST, instance=question)
        if form.is_valid():
            question = form.save(commit=False)
            question.modify_date = timezone.now() #수정일시 저장
            question.save()
            return redirect('pybo:detail', question_id=question.id)
    else:
        form = QuestionForm(instance=question)
    context = {'form':form}
    return render(request, 'pybo/question_form.html', context)


@login_required(login_url='common:login')
def question_delete(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    if request.user != question.author:
        messages.error(request, "삭제 권한이 없습니다")
        return redirect('pybo:detail', question_id=question.id)
    question.delete()
    return redirect('pybo:index')

 

3. answer_views.py

마찬가지입니다. 기존 views.py 에 있는 answer 관련 함수(answer_create, answer_modify, answer_delete) 와 import문을 복사 붙혀넣기한 다음에 Alt+Ctrl+O 키를 누릅니다.

정리된 import문에서 아래 구문의 .forms 와 .models 의 경로만 변경해줍니다. 

from .forms import AnswerForm    ===>>  from ..forms import AnswerForm
from .models import Question, Answer       ===>>  from ..models import Question, Answer
# Create your views here.

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 question_create(request):
    if request.method == 'POST':
        form = QuestionForm(request.POST)
        if form.is_valid():
            question = form.save(commit=False)
            question.author = request.user #author 속성에 로그인 계정 저장
            question.create_date = timezone.now()
            question.save()
            return redirect('pybo:index')
    else:
        form = QuestionForm()
    context = {'form': form}
    return render(request, 'pybo/question_form.html', context)


@login_required(login_url='common:login')
def question_modify(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    if request.user != question.author:
        messages.error(request, '수정 권한이 없습니다')
        return redirect('pybo:detail', question_id=question.id)
    if request.method == "POST":
        form = QuestionForm(request.POST, instance=question)
        if form.is_valid():
            question = form.save(commit=False)
            question.modify_date = timezone.now() #수정일시 저장
            question.save()
            return redirect('pybo:detail', question_id=question.id)
    else:
        form = QuestionForm(instance=question)
    context = {'form':form}
    return render(request, 'pybo/question_form.html', context)


@login_required(login_url='common:login')
def question_delete(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    if request.user != question.author:
        messages.error(request, "삭제 권한이 없습니다")
        return redirect('pybo:detail', question_id=question.id)
    question.delete()
    return redirect('pybo:index')
반응형

4. 기존 views.py 파일 삭제

이제 기존 mysite\pybo\views.py 파일을 삭제합니다.

 

5. pybo\urls.py 파일 수정

장고는 디버깅시 보통 urls.py 파일에서 URL에 매핑된 함수를 찾는 것으로 시작합니다. 그리하여 urls.py 파일에 base_views.py, question_views.py, answer_views.py 파일의 경로를 작성합니다.

msitte\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'),
]

 

6. config/urls.py 파일 수정

그리고 mysite/config/urls.py의 index에 해당되는 URL 매핑도 views 대신 base_views를 사용하도록 수정합니다.

from django.contrib import admin
from django.urls import path, include
from pybo.views import base_views      # <<-- 수정

urlpatterns = [
    path('admin/', admin.site.urls),
    path('pybo/', include('pybo.urls')),
    path('common/', include('common.urls')),
    path('', base_views.index, name='index'),  # '/' 에 해당되는 patt   << 수정
]

 

7. 확인

이제 서버를 재시작하고 잘 작동하는지 확인합니다