Code

==================
한눈에 보는 장고
==================

처음 장고는 뉴스편집 시스템으로 개발되었습니다. 그 덕분에 웹서비스를
쉽고 빠르게 개발할 수 있도록 설계되었습니다. 여기서는 장고로
데이터베이스를 이용한 간단한 웹 어플리케이션을 작성하는 예를
설명합니다.

이 문서에서 장고가 실제로 어떻게 동작하는지 충분한 기술적인 내용을
설명합니다. 다만 이 문서는 자세한 설명서나 참조문서가 아니기 때문에
좀더 자세한 내용은 장고 `도움말 문서`_를 참고하세요.

.. _도움말 문서: ../

모델(model) 설계
=================

데이터베이스 없이 장고를 사용한다고 해도 장고는 파이썬으로
데이터베이스 윤곽을 설명하는 객체-관계 매퍼(object-relational
mapper)를 가지고 있습니다.

데이터 모델(data-model) 구문으로 모델을 자세히 표현할 수
있습니다. -- 우리는 2년에 걸쳐서 데이터베이스 스키마를 표현하는 방법을
고안해냈습니다. 예를 들어서::

    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)
        article = models.TextField()
        reporter = models.ForeignKey(Reporter)

        def __unicode__(self):
            return self.headline

설치하기
==========

그럼 이제 장고의 명령행 스크립트로 데이터베이스를 자동으로
만듭니다.::

    manage.py syncdb

``syncdb`` 명령은 사용할 수 있는 모든 모델을 찾아서 데이터베이스에
테이블을 만듭니다.

API를 사용해보세요
==================

파이썬 API를 통해서 데이터에 접근하는 편리하고 풍부한 방법을
제공합니다. 코드를 미리 만들 필요 없이 바로 API를 사용할 수
있습니다.::

    >>> from mysite.models import Reporter, Article

    # 아직 기자가 없습니다.
    >>> Reporter.objects.all()
    []

    # 기자를 새로 추가합니다.
    >>> r = Reporter(full_name='John Smith')

    # save() 메소드로 데이터베이스에 객체를 저장합니다.
    >>> r.save()

    # ID가 있군요
    >>> r.id
    1

    # 이제 데이터베이스에 새 기자가 있군요.
    >>> Reporter.objects.all()
    [John Smith]

    # 데이터베이스 필드는 파이썬의 속성으로 표현됩니다.
    >>> r.full_name
    'John Smith'

    # 아래 방법으로 데이터베이스 쿼리를 표현할 수 있습니다.
    >>> Reporter.objects.get(id=1)
    John Smith
    >>> Reporter.objects.get(full_name__startswith='John')
    John Smith
    >>> Reporter.objects.get(full_name__contains='mith')
    John Smith
    >>> Reporter.objects.get(id=2)
    Traceback (most recent call last):
        ...
    DoesNotExist: Reporter does not exist for {'id__exact': 2}

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

    # Now the article is in the database.
    # 데이터베이스에서 기사를 확인합니다.
    >>> Article.objects.all()
    [Django is cool]

    # 기사(Article) 객체는 기자(Reporter) 객체에 관계(related) 모델로
    # 접근할 수 있습니다.
    >>> r = a.reporter
    >>> r.full_name
    'John Smith'

    # 반대로 기자(Reporter) 객체에서도 기사(Article) 객체에 접근할 수
    # 있습니다.
    >>> r.article_set.all()
    [Django is cool]

    # API는 필요에 따라서 관계(relationship)를 적용시킬 수 있습니다.
    # 효율적으로 JOIN을 사용하기 때문입니다.
    # 아래 코드는 "John"으로 시작하는 기자의 모든 기사를 가져옵니다.
    >>> Article.objects.filter(reporter__full_name__startswith="John")
    [Django is cool]

    # 속성을 변경시키고 save()해서 객체를 변경시킬 수 있습니다.
    >>> r.full_name = 'Billy Goat'
    >>> r.save()

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

동적인 관리 인터페이스: 단순한 스캐폴딩(scaffolding)이 아니라 그 이상입니다.
============================================================================

모델(model)을 정의하면 장고는 실제 운영에 적합한 전문적인 관리
인터페이스를 만들어냅니다. -- 등록된 사용자를 더하고, 바꾸고, 지우는
웹 사이트입니다. 모델에 한줄을 추가하는 것으로 쉽게 적용할 수
있습니다.::

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

아이디어는 이렇습니다. 운영자나 고객, 혹은 여러분이 사이트를
관리하면서 그 아래의 인터페이스까지 다룰 필요는 없어야 한다는
것입니다.

장고에서 웹 어플리케이션을 만드는 전형적인 과정은, 모델을 만들고 관리
사이트에서 관리하면서 최대한 빠르게 작동시키도록 합니다. 그래서 운영자
혹은 고객이 데이터를 만들어냅니다. 그리고 나서 데이터를 표현하도록
개발합니다.

URL 설계하기
================

깔끔하고 우아한 URL 구조는 웹 어플리케이션의 품질을 향상시키는 중요한
부분입니다. 장고는 `.php`, `.asp` 같은 군더더기 없이 URL을 이쁘게 만들
수 있도록 도와줍니다.

``URLconf``을 작성합니다. 어플리케이션의 목차라고 생각하시면 됩니다.
여기에는 URL 패턴(URL patterns)과 파이썬 콜백(Python callback)을
간단하게 연결시킵니다. ``URLconf``는 파이썬 코드에서 URL을 분리시키는
역할도 합니다.

아래에서는 ``Reporter/Article``라는 URL이 ``URLconf``에서 어떻게
표현되는지 설명합니다.::

    from django.conf.urls.defaults import *

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

간단하게 정규표현식(regular expressions)으로 표현된 URL과 파이썬
콜백(Python callback)의 위치를 연결시켰습니다. 정규표현식에서
괄호(``()``)를 이용해서 URL에서 값을 가져옵니다. 페이지가 호출되면
장고는 각 패턴(pattern)들을 순서대로 비교해서 먼저 일치하는 것을
선택합니다. (일치하는 패턴이 없으면, 장고는 404 뷰(view)를
호출합니다.) 장고가 처음 실행될 때 정규표현식을 읽어들이기 때문에 이
과정은 아주 빠르게 일어납니다.

일치되는 패턴(pattern)이 있으면, 장고는 패턴에서 정의한 간단한 파이썬
함수(function)인 뷰(view)를 호출합니다. 각 뷰(view)는 request
metadata를 가지고 있는 request 객체를 함께 넘겨받습니다. -- 그리고
앞에서 설명한 정규표현식으로 걸러낸 값들도 함께 넘겨받습니다.

아래 예에서 설명한 URLconf에서는 "``/articles/2005/05/39323/``"이라는
URL을 호출할 경우 장고는
`mysite.views.article_detail(request, '2005', '05', '39323')``라고
뷰(view)를 호출합니다.

뷰(view) 작성하기
================

뷰(view)는 두가지 일을 합니다.: 페이지 내용을 담고 있는
``HttpResponse`` 객체를 반환합니다. 혹은 ``Http404``라는 예외를
발생시킵니다.

보통은 뷰(view) 파라미터(parameters)에 따라서 데이터를 가져와서,
가져온 데이터와 템플릿(template)으로 페이지를 만듭니다. 아래 예에서는
위에서 설명한 ``year_archive`` 뷰(view)를 설명합니다.::

    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})

장고 템플릿(template)을 사용했습니다. 템플릿은 매우 강력한 방법이면서
프로그래머가 아니더라도 충분히 사용할 수 있습니다.

템플릿 디자인하기
=====================

위 예에서 ``news/year_archive.html`` 템플릿을 사용했습니다.

장고는 쉽게 템플릿을 가져오도록 템플릿 경로(template search path)를
사용합니다. 장고 설정(settings)에서 템플릿이 있는 디렉토리를
지정해줍니다. 첫번째 디렉토리에서 찾는 템필릿이 없으면 그 다음
디렉토리로 넘어갑니다.

다음과 같은 ``news/article_detail.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 속성(attribute)을
뜻합니다. 변수를 표현할 때 속성(attribute)뿐 아니라 사전의
키(dictionary-key), 리스트의 인덱스(index) 그리고 메소드까지 호출할 수
있습니다.

``{{ article.pub_date|date:"F j, Y" }}``에서처럼 유닉스에서 많이 사용되는
"pipe"("|")와 비슷하게 사용하는 템플릿 필터(template filter)를 사용할
수 있습니다. 이 필터는 원하는 형식으로 article.pub_date의 파이썬
datetime 객체를 바꿔줍니다. (PHP의 date 함수에서처럼; PHP에도 좋은
아이디어가 있군요.)

원하면 얼마든지 많은 필터를 결합시킬 수 있습니다. 필터를 직접 작성할
수도 있구요. 템플릿 필터, 템필릿 태그(template tags)도 작성할 수
있습니다.

마지막으로 장고는 "템플릿 상속(template inheritance)"이라는 개념이
있습니다.: 위 템플릿 예에서 ``{% extends "base.html" %}``이 바로
이것입니다. 블록 구조(blocks)를 정의한 "base.html"의 블록 구조를
사용한다는 뜻입니다. 이런 방법으로 템플릿의 중복을 극적으로
줄여줍니다.: 각각의 템플릿은 그 템플릿에 맞도록 정의되어야 합니다.

"base.html" 템플릿은 이렇게 생겼습니다.::

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

아주 단순하게 사이트의 모양(사이트 로고까지)을 정의했습니다. 그리고
"base.html"을 상속받는 다른 템플릿이 사용하도록 구멍(block)도
정의했습니다. 이 기본 템플릿을 사용해서 각 페이지의 템플릿을 변경하지
않고 "base.html"을 사용해서 사이트 모양을 바꿀 수 있습니다.

기본 템플릿만 다르게 해서 동일한 하위 템플릿을 이용해서 여러 모양의
사이트를 만들 수도 있습니다. 장고를 만든 저희들은 이 방법을 사용해서
새로운 기본 템플릿을 만들어서 하나의 사이트를 완전히 다른 핸드폰용
사이트로 사용하기도 했습니다.

장고의 모델(model)을 적용시킬 수만 있다면 다른 템플릿 시스템을
사용할 수도 있습니다. 좀더 들어가서, 장고의 데이터베이스 API도
마찬가지입니다. 다른 데이터베이스 API를 사용할 수도 있습니다.

    (역자주: 다른 데이터베이스 API를 사용할 수도 있지만, 몇가지 문제가
    있습니다.
        * 먼저 장고가 기본으로 제공하는 관리 사이트(admin site)를 사용할
          수 없습니다.
        * 그리고 장고에 포함된 폼 관련 라이브러리(newforms, forms) 등도
          사용할 수 없습니다.
    이런 장고 모델과 엮여있는 기능이 필요없다면 SQLObject나 SQLAlchemy 등
    파이썬의 ORM model을 사용하는 것도 좋은 시도입니다.)

데이터베이스 API, XML 파일 읽기, 디스크에서 파일 읽어들이기, 혹은
장고의 어떤 부분도 다른 것으로 대체할 수 있습니다. -- 모델(model),
뷰(view), 템플릿(template).
이상 맛보기였습다.
========================

빨리 장고를 기능 중심으로 살펴보았습니다. 다른 기능들도 살펴봅니다.:

    * memcached나 다른 백엔드를 사용하는 캐슁 프레임워크(caching
      framework).
    * RSS나 Atom 피드를 쉽게 만들어주는 `syndication framework`.
    * 매력적인 기능을 가진 관리 사이트(admin site).


이제 `장고를 다운로드`_해서
`첫번째: 처음 실행하기, 모델(model) 만들기, 데이터베이스 API`_를
읽어보세요. 그리고 `장고 사용자 모임`_에도 들러보세요. 관심을
가져주셔서 감사합니다.

.. _장고를 다운로드: http://www.djangoproject.com/download/
.. _첫번째: 처음 실행하기, 모델(model) 만들기, 데이터베이스 API: ../tutorial01/
.. _장고 사용자 모임: http://www.djangoproject.com/community/
Last modified 6 years ago Last modified on 11/14/07 06:53:59