Django tutorial1

By | 2014/06/17

django 튜토리얼1

쟝고의 기능들

  • ORMapper
  • Automatic admin interface
  • Elegant URL design
  • Template system
  • cache system
  • Internationalization

쟝고 설치됐는지 확인하기

python -c "import django; print(django.get_version())"

project 만들기

django-admin.py startproject mysite

위에꺼 실행하면 아래와 같은 디렉토리 & 파일이 생성됨

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py
  • manage.py : 커맨드라인 유틸리티. 자세한 것은 다음링크에서 확인가능 django-admin.py and manage.py
  • mysite 디렉토리 안의 mysite : 디렉토리가 실제 만들게될 프로젝트의 디렉토리
  • mysite/settings.py : 쟝고프로젝트 설정파일. 자세한 것은 다음 링크에서 Django settings
  • mysite/urls.py : 쟝고프로젝트의 URL정의 파일. 자세한 것은 다음 링크에서 확인 URL dispatcher
  • mysite/wsgi.py : WSGI과 호환되는 웹서버의 시작점. 자세한 것은 다음 링크로 How to deploy with WSGI
서버기동

python manage.py runserver

데이터베이스 세팅

디폴트는 sqlite3이고, 다른 데이터베이스를 사용하려면 mysite/settings.py의 DATABASES 부분을 수정해주어야한다. (나는 mongodb쓸껀데…) 데이터베이스 세팅에 관한 내용은 다음 링크에 있음 setting-DATABASE-ENGINE

타임존 설정(TIME_ZONE)

나는 대한민국 사람이니 mysite/settings.py 의 TIME_ZONE을 ‘Asia/Seoul’로 변경함. 기본은 ‘America/Chicago’
언어는 귀찮아서 냅둠.

설치된 앱들

settings.py에 보면 INSTALLED_APPS라는 파라메터가 있는데, 현재의 쟝고 인스턴스에서 활성화 된 쟝고 어플리케이션의 이름들을 적어놓은 곳이다. APP은 여러 프로젝트에서 사용가능하고 패키징하고 배포가 가능해서 다른 프로젝트에서도 사용될 수 있다.

디폴트로 포함되어 있는 앱들

  • django.contrib.admin – 관리자페이지
  • django.contrib.auth – 인증시스템
  • django.contrib.contenttypes – 컨텐트타입 프레임웤
  • django.contrib.sessions – 세션 프레임웤
  • django.contrib.messages – 메세징 프레임웤
  • django.contrib.staticfiles – 정적파일을 위한 프레임웤
syncdb

$ python manage.py syncdb

syncdb 커맨드는 INSTALLED_APPS의 설정을 보고 필요한 데이터베이스 테이블을 생성한다.
처음 실행할때 admin유저를 만들 수 있다.

app 만들기

python manage.py startapp polls

mysite의 탑레벨 모듈로 polls모듈을 만들자.

디렉토리는 아래와 같이 생겼다.

polls/
    __init__.py
    admin.py
    models.py
    tests.py
    views.py
모델만들기

polls/models.py 를 아래와 같이 고친다.

from django.db import models

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

하나의 클래스는 테이블과 매핑되고 하나의 변수는 하나의 필드와 매핑이 된다. 그리고 Choice클래스에 외래키를 지정했는데 django는 관계형디비의 모든 관계(다대다 일대다 일대일)를 지원한다.

모델 활성화하기

mysite/settings.py의 파일을 다시 열어서 아래와 같이 수정한다.

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',
)

이제 쟝고가 polls앱이 포함된 것을 알게됐다. 다음으로 아래의 명령을 실행해보자.

$ python manage.py sql polls

그러면 아래와 같은 SQL문이 콘솔에 찍힌다.

BEGIN;
CREATE TABLE "polls_poll" (
    "id" integer NOT NULL PRIMARY KEY,
    "question" varchar(200) NOT NULL,
    "pub_data" datetime NOT NULL
)
;
CREATE TABLE "polls_choice" (
    "id" integer NOT NULL PRIMARY KEY,
    "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL
)
;
  • 콘솔에 찍힌 SQL은 우리가 지정한 혹은 기본인 sqlite3 데이터 베이스에 사용되는 SQL문임을 알 수 있다.
  • 테이블명은 자동적으로 app(polls)과 소문자 모델클래스명을 결합하여 만들어진다.
  • 프라이머리키(IDs)는 자동으로 추가된다. (오버라이딩 가능)
  • 관례로, 쟝고는 ‘_id’를 외래키명에 붙인다.
  • 외래키 관계는 REFFERNCE문으로 정확히 만들어졌다.
  • sql명령어는 실제로 SQL을 실행하지는 않고 단순히 출력만 해준다.

관심있으면 아래 명령어도 테스트해보길

  • python manage.py validate – 모델이 유효한지 체크해줌
  • python manage.py sqlcustom polls – 테이블 변경이나 제약수정을 위한 명령어를 출력
  • python manage.py sqlclear polls – 테이블 삭제를 위한 쿼리를 출력
  • python manage.py sqlindexes polls – 인덱스 생성문을 출력
  • python manage.py sqlall polls – 해당앱에 사용된 모든 쿼리를 합쳐서 출력

syncdb로 모델의 테이블을 생성하자! (syncdb는 create만 해주고 alter는 해주지 않는다. 만약에 컬럼명이 변경된 경우 수동으로 고쳐야함)

API로 놀기

$ python manage.py shell managy.py가 DJANGO_SETTINGS_MODULE의 환경을 세팅해줌

>>> from polls.models import Poll, Choice
>>> Poll.objects.all()
[]

>>> from django.utils import timezone
>>> p = Poll(question="What's new?", pub_date=timezone.now())
>>> p.save()
>>> p.id
1

>>> p.question
"What's new?"
>>> p.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

>>> p.question = "What's up?"
>>> p.save()

>>> Poll.objects.all()
[<Poll: Poll object>]

마지막에 Poll object라고 나온거는 전혀 도움이 안되니 도움이 되는 문자열로 만들어보자.

polls/models.py 에 다음과 같은 메서드를 추가해주면 됨

from django.db import models

class Poll(models.Model):
    # ...
    def __unicode__(self):  # Python 3: def __str__(self):
        return self.question

class Choice(models.Model):
    # ...
    def __unicode__(self):  # Python 3: def __str__(self):
        return self.choice_text

메서드 하나를 또 추가해보자

import datetime
from django.utils import timezone
# ...
class Poll(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

python manage.py shell을 다시실행해서 놀아보자

>>> from polls.models import Poll, Choice

# Make sure our __unicode__() addition worked.
>>> Poll.objects.all()
[<Poll: What's up?>]

>>> Poll.objects.filter(id=1)
[<Poll: What's up?>]
>>> Poll.objects.filter(question__startswith='What')
[<Poll: What's up?>]

# Get the poll that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Poll.objects.get(pub_date__year=current_year)
<Poll: What's up?>

# Request an ID that doesn't exist, this will raise an exception.
>>> Poll.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Poll matching query does not exist.

# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Poll.objects.get(id=1).
>>> Poll.objects.get(pk=1)
<Poll: What's up?>

>>> p = Poll.objects.get(pk=1)
>>> p.was_published_recently()
True

>>> p = Poll.objects.get(pk=1)

>>> p.choice_set.all()
[]

>>> p.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> p.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = p.choice_set.create(choice_text='Just hacking again', votes=0)

>>> c.poll
<Poll: What's up?>

>>> p.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> p.choice_set.count()
3

>>> Choice.objects.filter(poll__pub_date__year=current_year)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]

>>> c = p.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

여기까지 했으면 인제 파트2로 넘어가도 됨. (튜토리얼은 6개까지 있음)