Django 한눈에 살펴보기

Django는 빠른 페이스의 뉴스룸 환경에서 개발되었기 때문에 일반적인 웹개발 작업을 빠르고 쉽게 하도록 디자인 되었습니다. 이것은 Django로 데이터베이스 기반의 웹 어플리케이션을 작성하는 것 에 대한 간략한 개요입니다.

이 문서의 목표는 Django가 어떻게 동작하는지 이해하는데 충분한 기술적 세부 사항을 전달하는 것 입니다. 이것은 튜터리얼이나 레퍼런스를 대신할수는 없습니다. 하지만 우린 그 두가지를 다 가지고 있지요! 프로젝트를 시작할 준비가 되었으면 튜터리얼로 시작 하거나 좀더 세부적인 문서로 곧장 뛰어들수 있습니다.

모델 설계

Django를 데이터베이스 없이 사용할수는 있어도 어쨋든 파이썬 코드로 데이터베이스 레이아웃을 설명하는 객체 관계 매퍼(ORM)이 제공됩니다.

데이터-모델 문법은 모델을 표현할수 있는 풍부한 방법을 제공합니다. – 지금까지, 이 기능들은 다양한 데이터 베이스 스키마 문제들을 해결해온 2년간의 실적이 있습니다. 다음의 간단한 예제는 mysite/news/models.py 로 저장하시면 됩니다.

class Reporter(models.Model):
    full_name = models.CharField(max_length=70)

    def __unicode__(self):
        return self.full_name

class Article(models.Model):
    pub_date = models.DateTimeField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)

    def __unicode__(self):
        return self.headline

설치하기

다음으로 데이터베이스 테이블을 자동으로 생성하기위해서 Django 명령줄 유틸리티를 실행합니다.:

manage.py syncdb

syncdb 명령어는 사용가능한 모든 모델을 찾아서 해당 테이블이 데이터베이스에 존재하지 않는다면 생성합니다.

공짜 API를 즐깁시다

데이터에 접근하는데 무료이면서 풍부한 Python API를 이미 가지고 있습니다. API들은 코드를 작성 할 필요도 없이 즉시 생성됩니다.:

# "news" 앱에서 생성한 모델을 Import
>>> from news.models import Reporter, Article

# 아직 시스템에 리포터가 없습니다.
>>> Reporter.objects.all()
[]

# 새로운 리포터를 생성합니다.
>>> r = Reporter(full_name='John Smith')

# 객체를 데이터베이스에 저장합니다. 이때 반드시 save() 를 명시적으로 호출해야만 합니다.
>>> r.save()

# 이제 ID가 생겼습니다.
>>> r.id
1

# 이제 새 리포터가 데이터베이스에 생성되었습니다.
>>> Reporter.objects.all()
[<Reporter: John Smith>]

# 필드는 파이썬 개체상의 어트리뷰트로 표현됩니다.
>>> r.full_name
'John Smith'

# Django는 풍부한 데이터베이스 조회 API를 제공합니다.
>>> Reporter.objects.get(id=1)
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__startswith='John')
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__contains='mith')
<Reporter: John Smith>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Reporter matching query does not exist.

# 기사를 생성합니다.
>>> from datetime import datetime
>>> a = Article(pub_date=datetime.now(), headline='Django is cool',
...     content='Yeah.', reporter=r)
>>> a.save()

# 이제 새 기사가 데이터베이스에 생성되었습니다.
>>> Article.objects.all()
[<Article: Django is cool>]

# 기사 개체는 연관된 리포터 개체에 접근할 API를 얻습니다.
>>> r = a.reporter
>>> r.full_name
'John Smith'

# 그리고 또한 역으로 리포터 개체는 기사 개체에 접근할 API를 얻습니다.
>>> r.article_set.all()
[<Article: Django is cool>]

# 작업하는데 필요한 관계형에 대한 API는 효율적으로
# JOIN작업을 뒤에서 수행 합니다.
# 이 코드는 "John"으로 시작하는 이름을 가진 리포터가 작성한 기사를 전체를 찾습니다.
>>> Article.objects.filter(reporter__full_name__startswith="John")
[<Article: Django is cool>]

# 개체의 속성을 변경시키고 save()를 호출합니다.
>>> r.full_name = 'Billy Goat'
>>> r.save()

# 개체를 delete()로 삭제합니다.
>>> r.delete()

동적인 관리자 인터페이스: 이건 단순한 뼈대 세우기가 아닙니다 – 이건 완성된 집 입니다

일단 모델이 정의 되었다면 Django는 전문적이고 바로 써먹을수 있는 관리자 인터페이스를 자동으로 만들수 있습니다 – 관리자 인터페이스는 인증된 사용자가 개체를 추가하고 변경하고 삭제할수 있는 웹사이트 입니다. 관리자 사이트에 모델 개체를 등록하는건 정말 쉽습니다.:

# In models.py...

from django.db import models

class Article(models.Model):
    pub_date = models.DateTimeField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)


# 같은 디렉터리의 admin.py...

import models
from django.contrib import admin

admin.site.register(models.Article)

운영자에 의해서나 고객, 혹은 단지 개발자 당신 스스로에 의해 수정될수 있는 이 사이트는 다음같은 철학을 가지고 있습니다. – 단지 컨텐츠를 관리하기위한 백엔드 인터페이스를 만드는데 힘을 쏟지 말자.

Django 앱을 생성하는 하나의 전형적인 작업 흐름은 일단 모델을 만들고 관리자 사이트를 올려서 가능한 빨리 작동할수 있게 만드는 것입니다, 그래서 당신의 운영자(혹은 고객)이 데이터 입력을 시작할수 있게 합니다. 그러면 밖으로 데이터를 표현하는 방법을 개발합니다.

URL 설계

깔끔하고 우아한 URL 계획은 고품질의 웹 어플리케이션에 매우 중요한 부분입니다. Django는 아름다운 URL 설계를 장려하며 URL에 .php.asp 같은 불필요한 내용들을 넣지 않습니다.

앱을 위한 URL을 설계하기위해서 URLconf 파이썬 모듈을 생성해야 합니다. 이것은 URL패턴과 파이선 콜백 함수간의 간단한 매핑 정보를 담고 있는 여러분의 앱에 대한 목차입니다. URLconf는 또한 파이썬 코드와 URL간의 결합도를 낮춰줍니다.

아래의 코드는 위의 Reporter/Article예제에 대해서 URLconf를 어떻게 쓰는지 보여줍니다:

from django.conf.urls import patterns, url, include

urlpatterns = patterns('',
    (r'^articles/(\d{4})/$', 'news.views.year_archive'),
    (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
    (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)

위 코드에서는 파이썬 콜팩함수(“views”)에 URL을 정규표현식으로 매핑 합니다. 정규 표현식은 괄호를 URL 에서 값을 “포착”해 오는데 사용합니다. 사용자가 페이지를 요청했을때 Django는 순서대로 각 패턴을 비교하고 요청된 URL과 처음으로 매칭되는곳에서 멈춥니다. (만약 아무것도 매칭되는것이 없다면 Django는 special-case 404 view를 호출합니다) 이 방식은 엄청나게 빠릅니다, 왜냐하면 정규 표현식은 로딩되는 시점에 컴파일되기 때문입니다.

한번 정규 표현식 하나가 매치되면 Django는 간단한 파이썬 함수인 view를 import하고 호출 합니다. 각 view는 request object – 각 요청에 대한 메타 데이터를 담고 있는 – 와 정규표현식으로 URL로 부터 포착한 값을 전달 받게 됩니다.

예를 들어 사용자가 URL “/articles/2005/05/39323/”로 요청을 보냅니다, 그러면 Django 는 다음처럼 함수를 호출하게 됩니다 news.views.article_detail(request, '2005', '05', '39323').

view의 작성

각각의 뷰는 다음의 두가지 중에 하나를 수행할 책임이 있습니다.: 요청된 페이지의 내용을 담고 있는 HttpResponse 객체를 반환 하거나, Http404와 같은 예외를 발생시키는 것 입니다. 나머지는 여러분에게 달려있습니다.

일반적으로 뷰는 파라미터들에 따라 데이터를 가져오며 템플릿을 로드하고 템플릿을 가져온 데이타로 렌더링 합니다. 아래는 위에서 만든 year_archive 에 대한 예제 뷰 입니다.:

def year_archive(request, year):
    a_list = Article.objects.filter(pub_date__year=year)
    return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list})

이 예제는 Django의 template system 을 사용합니다. Djago 템플릿 시스템은 몇몇 강력한 기능들을 가지고 있지만 프로그래머가 아닌 사람도 사용하기에 어렵지 않도록 간결함을 유지하도록 노력하였습니다.

나만의 템플릿 작성

위의 코드는 news/year_archive.html 템플릿을 로드합니다.

Django는 템플릿들 간의 중복을 최소화 할수 있도록 템플릿 검색경로를 가지고 있습니다. 여러분의 Django 설정에서 템플릿들을 불러올 디렉토리 목록을 정의합니다. 만약 첫번째 디렉토리에서 템플릿이 존재하지 않는다면 두번째 를 확인하고 이런식으로 쭉 나아갑니다.

news/year_archive.html 템플릿을 발견 했다고 합시다. 아마도 이런 모양일 것입니다.:

{% extends "base.html" %}

{% block title %}Articles for {{ year }}{% endblock %}

{% block content %}
<h1>Articles for {{ year }}</h1>

{% for article in article_list %}
    <p>{{ article.headline }}</p>
    <p>By {{ article.reporter.full_name }}</p>
    <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}

변수는 이중 중괄호로 둘러싸입니다. {{ article.headline }} 위 코드의 뜻은 “article의 headline 어트리뷰트의 값을 출력하겠다.” 입니다. 하지만 점(.)이 어트리뷰트의 조회에만 사용되는것은 아닙니다. 점은 사전의 키 조회에도 사용될수 있으며 인덱스 조회와 함수 호출에도 사용될수 있습니다.

참고로 {{ article.pub_date|date:"F j, Y" }} 는 유닉스 스타일의 “파이프”를 사용한것입니다(“|” 문자). 이 파이프는 템플릿 필터를 호출하며 이를 통해 변수의 값을 필터링 할 수 있습니다. 이 코드에서 date 필터는 파이썬의 datetime 개체를 지정한 포멧으로 변환 시킵니다.(PHP의 date 함수처럼 말이죠, 네 PHP 의 좋은 아이디어중에 하나 입니다.)

여러분은 원하는데로 많은 수의 필터를 연결시킬수 있습니다. 그리고 뒤에서 커스텀 파이썬 코드를 실행시키는 커스텀 탬플릿 태그들을 작성할수 있습니다.

이제 마지막으로 Django의 “템플릿 상속” 개념을 사용해 보죠. 이를 통해 {% extends "base.html" %} 코드가 무슨일을 하는지 알수 있습니다. 이 코드의 의미는 ” 한뭉치의 block들이 정의된 ‘base’라는 템플릿을 먼저 로드하고 뒤따르는 block들로 이 block들을 채운다는것” 입니다. 간단히 말해 템플릿안의 중복을 극적으로 낮추게 합니다. 각각의 템플릿은 자신이 표현하려는 내용들만 정의할수 있게 되니까요.

“base.html” 템플릿이 이런식으로 채워져 있을것입니다:

<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="sitelogo.gif" alt="Logo" />
    {% block content %}{% endblock %}
</body>
</html>

간단하게 사이트의 룩앤필(사이트의 로고)을 정의하고 자식 템플릿이 내용을 채워넣을 “구멍”들을 제공합니다. 이러한 방식은 사이트의 재 디자인을 ‘base’템플릿 파일 하나를 바꾸는것 같이 쉬운 방법으로 가능하게 해줍니다.

또한 자식 템플릿을 재활용해서 서로 다른 base 템플릿으로 여러 버전의 사이트를 만들수 있게 합니다. Django의 제작자는 이러한 테크닉으로 완전히 다른 모바일 버전의 사이트를 만들었습니다. 간단히 새로운 base 템플릿을 만드는것으로 말이죠.

여러분이 선호하는 템플릿 시스템이 있다면 꼭 Django의 템플릿 시스템을 사용할 필요가 없다는건 알아두세요. Django의 템플릿 시스템은 Django의 모델계층과 매우 잘 통합되어 있지만 꼭 이를 사용하도록 강제하는건 아닙니다. 이러한 이유들로 Django의 database API 역시 반드시 써야할 필요는 없습니다. 여러분은 다른 데이터베이스 추상화 계층을 사용할수 있으며 XML 파일이나 디스크에서 다른파일을 사용하거나 여러분이 원하는 다른 여러가지 방식으로 사용할수도 있습니다. 각각의 Django 구성요소들 – 모델, 뷰, 템플릿 – 은 서로 결합도가 낮게 되어있습니다.

이건 단지 껍데기 일뿐

이건 Django의 기능에 대한 간략한 개요에 불과합니다. 다음과 같이 좀더 유용한 기능들도 많습니다:

  • memached와 통합되어 있는 caching framework 이지만 다른 백엔드도 사용가능 합니다.
  • A syndication framework 는 RSS와 Atom 피드를 매우 적은 파이썬 클래스 작성으로 쉽게 만들어줍니다.
  • 아주 매력적인 자동 생성 관리자 기능 – 이 개요문서는 맛보기 일 뿐입니다.

여러분이 반드시 해야할 다음 단계는 download Django, the tutorial 그리고 the community 참여 입니다. 여러분의 관심에 감사드립니다.