본 글은 Django framework 공식문서에서 소개하는 설치 과정과 제시하는 MTV패턴을 중심으로 tutorial의 핵심 요소를 정리한 글입니다.
Django
는 파이썬으로 작성된 고수준 웹 프레임워크로, 신속한 개발과 깔끔한 디자인을 가능하게 합니다. Django
는 "batteries-included" 철학을 따르며, 많은 기능을 내장하여 웹 개발에 필요한 거의 모든 것을 제공합니다.
Django는 MTV 패턴
을 따릅니다. MTV
는 Model-Template-View의 약자로, 흔히 우리가 아는 MVC(Model-View-Controller) 패턴
의 변형입니다. Django에서는 View가 실제로 비즈니스 로직을 처리하는 것이 아니라, 템플릿 시스템을 사용하여 데이터를 표시하는 역할을 합니다.
Model
: 데이터베이스 구조를 정의합니다. 데이터의 필드와 동작을 정의하며, 데이터베이스와의 상호 작용을 관리합니다.Template
: 사용자에게 표시될 화면을 정의합니다. HTML과 Django 템플릿 언어를 사용하여 데이터를 렌더링합니다.View
: 요청을 처리하고 적절한 템플릿을 선택하여 응답을 반환합니다. 비즈니스 로직을 구현하고, 모델과 템플릿을 연결합니다.
이제 공식문서에서 제시하는 가이드라인에 따라 Django를 설치해보고, 간단하게 구성 요소를 살펴봅시다.
기존 환경에서 실행해도 상관은 없지만 여러 프로젝트의 버젼 충돌로 인한 에러를 방지하기 위하여 virtual environment를 구축하는것이 바람직하다
py -m venv project-name
project-name\Scripts\activate.bat
deactivate
py -m pip install Django
django-admin –version
$ django-admin startproject mysite
$ python manage.py runserver
$ python manage.py startapp polls ## polls -> App 이름
생성된 앱을 서버에서 구축하기 위해서는 urls path와 settings를 관리해야 합니다.
참고로, 아래에서 언급되는 urls.py
파일은 쉽게 설명하면 API request path를 관리하는 파일이라고 보면 됩니다. (ex: Node.js 프로젝트에서 관리하는 index.ts 파일)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("polls/", include('polls.urls'))
]
from django.urls import path
from . import views
urlpatterns = [
path('',views.index, name='index')
path('some_url',views.some_url)
]
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls.apps.PollsConfig',
]
장고의 model은 RDB의 개념이라고 생각하면 쉽다.
따라서 SQL과 같이 schema를 생성하고 attribute을 추가하고 이에 대한 filtering이 가능하다.
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
화면단 구현에 필요한 각각의 html 파일은 template 디렉토리에서 보통 관리한다.
index.html
예시
{% if questions %}
<ul>
{% for question in questions %}
<li>{{question}}</li>
{% endfor %}
</ul>
{% else %}
<p>no questions</p>
{% endif %}
각각의 html파일을 함수 단위로 manage한다.
from .models import *
from django.shortcuts import render
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'questions': latest_question_list}
return render(request, 'polls/index.html', context)
def detail(request, question_id):
question = Question.objects.get(pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
참고로, render는 간단하게 말하면 html파일을 화면에 보이게 만들어 주는 것이라고 이해하면 된다.
추가한 view의 결과를 보기 위해서는 path를 추가해야한다
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.index, name='index'),
path('some_url', views.some_url),
path('<int:question_id>/', views.detail, name='detail'),
]
404에러: http에서 요청한 페이지를 찾을 수 없을 때 생기는 에러
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
Solve: 두개의 서버가 아닌 하나의 DB에서 처리
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {'question': question, 'error_message': f"선택이 없습니다. id={request.POST['choice']}"})
else:
selected_choice.votes = F('votes') + 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:index'))
- django에는 관리자 페이지 및 관리자 기능을 할 수 있는 admin.py를 제공한다
- 관리자 페이지에서 보여질 모델의 필드, 필터링 기준, 검색 기준 등을 설정할 수 있으며, 모델에 대한 CRUD(CREATE, READ, UPDATE, DELETE) 작업을 수행하는 메소드도 정의할 수 있다.
- 쉽게 말하면 Admin을 활용하여 DB의 내용 관리(CRUD)를 손쉽게 할 수 있다는 것이다.
from django.contrib import admin
from .models import Choice, Question
admin.site.register(Choice)
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
('질문 섹션', {'fields': ['question_text']}),
('생성일', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
readonly_fields = ['pub_date']
inlines = [ChoiceInline]
list_filter = ['pub_date']
search_fields = ['question_text', 'choice__choice_text']
admin.site.register(Question, QuestionAdmin)
지금까지 공식문서를 따라, Django
아키텍처 내에서 MTV패턴
이 대략적으로 어떤 구조로 구현되고, 에러에 대한 관리와 admin 기능을 어떻게 코드로 관리하는지에 대해 알아보았다.
이후, tutorial에서 제시하는 가이드라인을 전체 구현한 코드는 아래 github repository에 업로드 해놓았습니다 :)
GitHub - idle-danie/django_study: django_study_tutorial