SlideShare una empresa de Scribd logo
1 de 113
Descargar para leer sin conexión
Django In Action
    This session brought to you by SMARTSTUDY
박현우

@lqez
2001-2006 NHN
2007-2010 NPLUTO
2010-현재 SMARTSTUDY


게임 개발자로 시작,
10년간 업계에서 구르다 지금은
걍 카페코딩 좋아하는 SCV.
스마트스터디
2010년 설립,
삼성출판사의 자회사


게임 업계에서 실컷 굴러본 경력!
+ 실력과 열정 넘치는 멋진 신입!


유아동 애플리케이션 +
만화, 동영상, 게임이 주력 사업.
양질의 콘텐츠를 수급하여,
좋은 서비스를 만드는 것이 목표!
OK,	 회사	 소개는
  거기까지.
Session A


            •Django 소개
            •장단점
            •우리는 왜?
            •직접 경험하기
역사


 • Lawrence.com PHP 기반 웹사이트 유지보수를 위해.1
 •개발자가 좋아하던 기타리스트인 Django Reinhardt 의
     이름을 따서 지음.




 [1] http://www.quora.com/What-is-the-history-of-the-Django-web-framework
특징

 • Full Stack Framework
  •웹 페이지를 만들기 위한 대부분의 요소가 포함되어 있음.
     • HTTP Request / Response 처리, URL 패칭
     • 템플릿 엔진
     • ORM

 •Lawrence.com 은 언론 / 뉴스 사이트.
  •개발 당시 부르던 내부 이름은 ‘The CMS’.
  •따라서, Admin 프레임워크가 잘 갖춰져 있다.
역할

                      HTTP Request
 http://foo.com         Parsing                  Query

 Users       Web Servers       Web Application           Data


 HTTP Response          HTML Page            QuerySet
                       JSON Result
역할

                     HTTP Request
 http://foo.com        ParsingURL             ORMQuery
                                Dispatcher

 Users       Web Servers WSGI      Web Application       Data

                                Template
 HTTP Response          HTML    Page
                                 Engine           QuerySet
                                             Serializer

                       JSON Result
                                Django
역할, 그리고
                 Sessions      Authentication
                                                  Cache Backend
                & Cookies      & Authorization

               Error     HTTP Request                     Database
 http://foo.com
             Reporting     ParsingURL               ORMQuery
                                                           Router
                                    Dispatcher

 Users         Web Servers WSGI
            Admin Page                   Web Application      Aggregation
                                                                  Data

                                     Template
 HTTP Response                HTML   Page
                                      Engine           QuerySetSQL
                                                  Serializer
                                                             RAW
           Testing
                             JSON Result
                                Internalization
                  Security                        Forms     Logging
                                & Localization



                                     Django
... 거기에 더해




    http://www.djangopackages.com/
그래서,


          Django is
 Full Stack Web Framework
그런데,
                 Sessions       Authentication
                                                   Cache Backend
                & Cookies       & Authorization

               Error      HTTP Request                       Database
 http://foo.com
             Reporting      ParsingURL                SQL Query
                                                     ORM
                                                              Router
                                     Dispatcher     Alchemy

 Users         Web Servers WSGI
            Admin Page                    Web Application      Aggregation
                                                                   Data

                                      Template
 HTTP Response
            BDD                HTML   Page2
                                       Jinja
                                       Engine           QuerySetSQL
                                                   Serializer
                                                              RAW
           Testing
                Toolkit
                              JSON Result
                                 Internalization
                   Security                        Forms     Logging
                                 & Localization



                                      Django
그런데,
                 Sessions       Authentication
                                                   Cache Backend
                & Cookies       & Authorization

               Error      HTTP Request                       Database
 http://foo.com
             Reporting      ParsingURL                SQL Query
                                                     ORM
                                                              Router
                                     Dispatcher     Alchemy

 Users         Web Servers WSGI
            Admin Page                    Web Application         Aggregation
                                                                      Data


 HTTP Response
                                FAILEDTemplate
                                      QuerySet
            BDD
           Testing
                               HTML   Page2
                                       Jinja
                                       Engine
                                                   Serializer
                                                                 RAW SQL
                Toolkit
                              JSON Result
                                 Internalization
                   Security                        Forms        Logging
                                 & Localization



                                      Django
대안은?
 •Werkzeug
  • The Python WSGI Utility Library
    • HTTP Request parsing / Response objects
    • URL Dispatching
 •Flask
  • a micro-framework for Python based on Werkzeug
    • Jinja 2 / Unit test / RESTful dispatching / Cookies
  • 국내에선,
    • 패션 SNS - StyleSha.re
       •   http://engineering.stylesha.re/post/28761152299/styleshare-service-stack

    • 모바일 소셜 포인트 카드 -                DoDo / Spoqa 등이 사용중.

       •   http://spoqa.github.com/2012/01/16/wsgi-and-flask.html
장단점

 • Full Stack Framework
  •장점 : 하나만 배우면 된다.
  •단점 : 하나라도 제대로 이해하고 쓰기는 어렵다.

 • Micro Framework
  •장점 : 레고를 조립하듯 입맛대로 서비스를 구성할 수 있다.
  •단점 : 뭐든지 찾아써야 한다.
우리는 왜 Django를 선택했나.

 •PHP로 더 이상 심각한 웹 개발을 하고 싶지 않다.
   • 딱히 싫어하는건 아니지만...
 •왜 Python을?
   • 예전부터 써봤었고,
   • 각종 스크립트도 작성해서 쓰고 있었기에,
   • 웹 개발을 위해 별도로 Ruby나 Perl 등을 배우고 싶진 않다!
 •하지만 웹 개발 전문가라 부를 사람이 없었음.
 •와중에 10분만에 Django로 블로그 만들기 등을 보게 됨.
   • http://www.lightbird.net/dbe/blog.html
이거다! 선택의 여지가 없다!
아... 안돼!

  •아쉬운 점
   •생각보다 정적 페이지 구성이 없음.
   •애초에 Heavy AJAX 형태의 웹 서비스를 위한 구조가 아님.
      • Paginator 같은 건 당연히 필요 없음.
   •폼 처리가 거의 없다보니 매력 감소.
   •기본 제공 관리 페이지가 우리에게 그리 쓸만하지 않음.
      • User가 10만명이 넘어가는데, 해당 모델을 포함한 관리 페이지에서 10만개의
        OPTION 태그로 그냥 출력해버리는 대범함... 당연히 엄청 느림.
Django 장점 정리

 1. 어쨌거나 웹 개발의 껍질만 배우고도 시작할 수 있다.
 2. 한국어/한글로 된 도서도 있다! (...)
 3. 각종 추가 모듈의 도움으로 간편하게 기능 확장!
 4. 가볍게 데이터를 읽고 쓰기엔 기본 ORM도 나쁘지 않다.
 5. 기본 템플릿 엔진도 그럭저럭 쓸만함.
 6. 썩어도 준치, 없는 것보단 나은 기본 관리 페이지.
Django 장점 정리

 1. 어쨌거나 웹 개발의 껍질만 배우고도시작 수 있다.
                       시작할
  한국어
 2. 한국어/한글로 된 도서도 있다! (...)
     추가 모듈
 3. 각종 추가 모듈의 도움으로 간편하게 기능 확장!
 4. 가볍게 데이터를 읽고 쓰기엔기본ORM도 나쁘지 않다.
                   기본 ORM
 5.기본 템플릿 그럭저럭 쓸만함.
   기본 템플릿 엔진도
 6. 썩어도 준치, 없는 것보단 나은 관리 페이지
                      기본 관리 페이지.
하지만 여러분에겐,

  •먼저 삽질한 스마트스터디가     있습니다.       미약하나마


  •오늘 실습이 선택에 도움이 되길 바랍니다.
  •페이스북 그룹도 있더군요.
    • https://www.facebook.com/groups/django/
    • 꽤 활발합니다!
  •IRC도 있습니다.
    • #django / irc.ozinger.org
    • 하루 종일 아무도 말 안합니다...
Session B

                              어쨌든
                              우리는
                              오늘
                              웹툰을
                              만들껍니다.
        웹툰 화면은 네이버 웹툰(http://m.comic.naver.com)에서 발췌.
...물론 현실은,




                     대략 이 정도...?




      모든 이미지는 http://www.projectcartoon.com/ 에서 발췌.
Step 0. 알고가기
•터미널 / 쉘에서 직접 실행하기 ( 초록색 배경 )
> dir
$ ls

•소스 수정 ( 검은색 배경 )
 • 대부분의 경우 덮어쓰기 보다는 부분 수정이 많으니 주의해주세요.
# 이미 입력되어 있던 소스 - 하얀색
from webtoon.models import *
(...) - 생략된 부분

# 새로 입력해야 하는 소스 - 노란색
def home(request):
    return HttpResponse(output)
•Python은 들여쓰기(Indentation)을 탭, 또는 빈칸으로 합니다.
 •하나의 소스 파일 내에서는 같은 들여쓰기 규칙을 유지합니다.
 •섞어 쓰면 문법 오류가 발생.
•실습에서 .py / .html 파일은 모두 UTF-8 인코딩을 사용합니다.
 •.py 에서도 한글을 사용하려면 아래 내용을 첫 줄에 넣습니다.
# -*- coding: utf-8 -*-
Step 1. 준비


  •Python
  •setuptools / pip
  •VirtualEnv / VirtualEnvWrapper
   •소개 : http://blog.naver.com/ez_/140138625021
•Windows
 •기본으로 Python이 없으니, Python부터 설치합니다. 2.7을 선택해주세요.
 • http://python.org/download/
     • 인스톨러를 통해 편리하게 설치할 수 있습니다.
     • 환경 변수 PATH에 아래 경로를 추가합니다.
        •   C:Python27;C:Python27Scripts;

     • 환경 변수 PYTHONHOME을 지정합니다.
        •   C:Python27

 •   http://pypi.python.org/pypi/setuptools
     • 32bit : http://pypi.python.org/packages/2.7/s/setuptools/
        setuptools-0.6c11.win32-py2.7.exe 를 다운받아 실행.

     • 64bit : http://peak.telecommunity.com/dist/ez_setup.py      를 다운받
        아 python ez_setup.py 로 실행.
•Windows (이어서 계속)
> easy_install pip
> pip install virtualenvwrapper-win


•OS X / Linux
$ sudo easy_install pip
$ sudo pip install virtualenvwrapper
$ source /usr/local/bin/virtualenvwrapper.sh


•OS X 에서 distutils 오류 발생시, 아래 명령어 수행.
$ sudo touch /System/Library/Frameworks/Python.framework/
Versions/2.7/lib/python2.7/distutils/__init__.py

   http://stackoverflow.com/questions/3129852/python-cant-locate-distutils-path-on-mac-osx
•OS X / Linux 에서 ~/.profile 에 아래 내용 추가
source /usr/local/bin/virtualenvwrapper.sh
# 가상 환경 위치를 바꾸고 싶으면 WORKON_HOME 수정
# 기본 위치는 ~/.virtualenvs
export WORKON_HOME=~/VirtualEnvs
Step 2. Django 설치



  •mkvirtualenv
  •workon / deactivate
  •pip install django
$ mkvirtualenv webtoon
New python executable in webtoon/bin/python
Installing setuptools............done.
Installing pip...............done.
(...)

(webtoon)$ deactiviate

$ workon
(...이미 생성된 가상 환경들의 목록...)

$ workon webtoon
(webtoon)$
(webtoon)$ pip install django
Downloading/unpacking django
  Downloading Django-1.4.1.tar.gz (7.7Mb): ...
  Running setup.py egg_info for package django

Installing collected packages: django
  Running setup.py install for django
(...)
Successfully installed django
Cleaning up...
(webtoon)$
•잘 설치되었는지 확인!
(webtoon)$ python
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53)
>>> import django
>>> django.VERSION
(1, 4, 1, 'final', 0)
>>>
•Windows
 •copy <홈 디렉토리>EnvsLibsite-packagesdjangobin
   django-admin.py c:Python27Scripts
   • 위와 같이 미리 복사해주시면 편합니다.
   • 보통 홈 디렉토리는 ‘C:Document and settings사용자 이름’
Step 3. 드디어 시작!


 •django-admin.py startproject mysite
 •python manage.py runserver

 •https://docs.djangoproject.com/en/1.4/intro/
(webtoon)$ django-admin.py
(...)
(webtoon)$ django-admin.py startproject mysite
(webtoon)$ cd mysite/
(webtoon)$ ls
manage.py mysite
(webtoon)$ python manage.py runserver
Validating models...

0 errors found
Django version 1.4.1, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

   •Windows 의 경우,
    •python c:Python27Scriptsdjango-admin.py ...
Step 4. 웹툰 시작



 •django-admin.py startapp webtoon
 •settings.py 의 INSTALLED_APP 에 추가
 •urls.py 에 뷰 등록
(webtoon)$ python manage.py startapp webtoon
(webtoon)$ ls
manage.py mysite    webtoon
(webtoon)$


   •App 을 project 와 같은 위치에 만드는 이유
    •‘... it can be imported as its own top-level
        module, rather than a submodule of mysite.’
     •https://docs.djangoproject.com/en/1.4/intro/
        tutorial01/#creating-models
•mysite/settings.py

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # ...

    'webtoon',
)
•mysite/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3'
        'NAME': 'mysite.db',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }
}
Step 5. 모델


  •User
  •Comic
  •Episode
  •Author
  •Comment
•webtoon/models.py
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=200)
    desc = models.TextField()

   •https://docs.djangoproject.com/en/dev/ref/models/fields
(webtoon)$ python manage.py syncdb
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table webtoon_author

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'lqez'): lqez
E-mail address: ez@smartstudy.co.kr
Password:
Password (again):
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
(webtoon)$
•OS X / Linux 에서 LANG 관련 오류가 발생한다면,
 •LANG 환경 변수가 잘못 정의되어 있거나 비어있어서 발생.
 •https://code.djangoproject.com/ticket/5846
 •아래와 같이 임시로 환경 변수를 설정하여 문제 회피 가능.
$ export LANG=en_US.UTF-8
$ export LC_CTYPE=en_US.UTF-8
(webtoon)$ python manage.py shell
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53)
(InteractiveConsole)
>>> from webtoon.models import *
>>>
>>> new_author = Author()
>>> new_author.name = "주호민"
>>> new_author.desc = "파주스님"
>>> new_author.save()
>>>
>>> authors = Author.objects.all()
>>> authors
[<Author: Author object>]
>>>
•webtoon/models.py
class Author(models.Model):
    name = models.CharField(max_length=200)
    desc = models.TextField()

   def __unicode__(self):
       return self.name


(webtoon)$ python manage.py shell
>>> from webtoon.models import *
>>> authors = Author.objects.all()
>>> authors
[<Author: 주호민>]
>>>
•webtoon/models.py
class Author(models.Model):
    name = models.CharField(max_length=200)
    desc = models.TextField()

   def __unicode__(self):
       return self.name


(webtoon)$ python manage.py shell
>>> from webtoon.models import *
>>> authors = Author.objects.all()
>>> authors
[<Author: 주호민>]
>>>
•Django 의 ORM 기능에 대한 소개는,
 •https://docs.djangoproject.com/en/1.4/ref/models/querysets/
 •https://docs.djangoproject.com/en/1.4/topics/db/queries/
Step 6. 관리 페이지


 •admin 모듈 추가.
 •내가 만든 모델을 admin에 노출하기.
 •ModelAdmin 상속 받아 확장하기.
 •MEDIA / STATIC 파일 이해.
•mysite/settings.py
INSTALLED_APPS = (
    # ...
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    'webtoon',
)

    •mysite/urls.py
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # ...
    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)
•관리자 페이지 이용을 위한 로그 테이블 생성
(webtoon)$ python manage.py syncdb
Creating tables ...
Creating table django_admin_log
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
(webtoon)$
•http://localhost:8000/admin
•webtoon/admin.py (파일이 없으니 생성해주세요)
   •대부분의 경우 runserver 에서 자동으로 다시 읽어주나,
   •이 경우는 자동으로 읽어주지 않으니, 종료 후 다시 실행해주세요.

from webtoon.models import *
from django.contrib import admin

admin.site.register(Author)
•http://localhost:8000/admin
•webtoon/admin.py
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('name', 'desc')
admin.site.register(Author, AuthorAdmin)
•링크를 통해 완성된 소스를 받아주세요.
     •webtoon/models.py
       • https://gist.github.com/3367067
     •webtoon/admin.py
       • https://gist.github.com/3368666

(webtoon)$ python manage.py syncdb
Creating tables ...
Creating table webtoon_episode
Creating table webtoon_comic
Creating table webtoon_comment
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
(webtoon)$
•mysite/settings.py
    •MEDIA_ROOT : 미디어 파일이 실제 저장될 위치
    •MEDIA_URL : 어떤 URL로 미디어 파일을 전달할 것인가
    •이미 settings.py 에 변수가 있으니, 찾아서 변경해주세요.
import os.path
MEDIA_ROOT = os.path.join(os.path.dirname(__file__),"media/")
MEDIA_URL = '/media/'
•mysite/urls.py
import os.path
urlpatterns = patterns('',
    ...
    (r'^media/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root':
         os.path.join(os.path.dirname(__file__),'media')}
    ),
)

   •STATIC / MEDIA 파일 전달
    •원래 Django 의 역할이 아님.
    •개발 편의를 위해 django.views.static.serve 사용
    •Production 에서는 절대 사용 금지!
•샘플 데이터베이스 및 파일 다운로드
 •데이터베이스
  • http://dl.dropbox.com/u/16168259/mysite.db
  • manage.py 가 있는 위치에 있는 mysite.db 에 덮어 씌우세요.
  • 관리자 ID : test / PW : test
 •이미지 파일
  • http://dl.dropbox.com/u/16168259/comics.zip
  • 압축 해제 후, mysite/media/comics 안에 모든 jpg 파일을 복사해주세요.
  • 모든 이미지는 네이버와 각 작가분에게 저작권이 있습니다. (?)
Step 7. 뷰와 템플릿


 •뷰 준비하기
 •템플릿 만들어보기
 •상속된 템플릿
 •템플릿 필터
 •컨텍스트 프로세서
•아래와 같은 URL로 웹 서비스를 하려고 합니다.
 •웹툰 홈페이지
  • /webtoon
 •작가 페이지
  • /webtoon/author/작가
 •만화 페이지
  • /webtoon/만화
 •에피소드 페이지
  • /webtoon/만화/에피소드
•mysite/urls.py
url(r'^webtoon/$',
    'webtoon.views.home', name='webtoon'),
url(r'^webtoon/author/(?P<author_id>d+)/$',
    'webtoon.views.author', name='author'),
url(r'^webtoon/(?P<comic_id>d+)/$',
    'webtoon.views.comic', name='comic'),
url(r'^webtoon/(?P<comic_id>d+)/(?P<episode_id>d+)/$',
    'webtoon.views.episode', name='episode'),

url(r'^webtoon/$',
    'webtoon.views.home', name='webtoon'),
url(r'^webtoon/author/(d+)/$',
                                                •Named parameter
    'webtoon.views.author', name='author'),
url(r'^webtoon/(d+)/$',
    'webtoon.views.comic', name='comic'),
                                                 •처음엔 좀 복잡해 보이지만,
url(r'^webtoon/(d+)/(d+)/$',
    'webtoon.views.episode', name='episode'),
                                                 •의미 전달에 용이
•webtoon/views.py
from django.http import HttpResponse

def home(request):
    return HttpResponse('Home of webtoon service')

def author(request, author_id):
    return HttpResponse('Author %s page' % author_id)

def comic(request, comic_id):
    return HttpResponse('Comic %s page' % comic_id)

def episode(request, comic_id, episode_id):
    return HttpResponse('Episode %s of Comic %s page' %
                            (episode_id, comic_id) )
•웹툰 홈페이지
   http://localhost:8000/webtoon

•작가 페이지
   http://localhost:8000/webtoon/author/1

•만화 페이지
   http://localhost:8000/webtoon/1

•에피소드 페이지
   http://localhost:8000/webtoon/1/1



•URL 마지막에 자동으로 / 붙음.
   settings.APPEND_SLASH = True

 • HTTP 301 로 Redirection 시키므로, 원하지 않는 경우 url을 잘 설정
   하고 해당 기능을 꺼야 함.
•webtoon/views.py
from django.template.context import RequestContext
from django.template.loader import get_template

def home(request):
    template = get_template('home.html')

   variables = RequestContext(request, {})
   output = template.render(variables)

   return HttpResponse(output)

(...)
•webtoon/templates/home.html
      • 공용 템플릿은 프로젝트 디렉토리의 templates 에,
      • 앱의 템플릿은 앱 디렉토리의 templates 에 놔두면 좋습니다.
<html>
<head>
    <meta charset="utf-8" />
    <title>Django 웹툰</title>
</head>
<body>
    <h1>Django 웹툰</h1>
    <p>Django 웹툰에 오신 것을 환영합니다.</p>
</body>
</html>
•webtoon/templates/home.html
<html>
<head>
    <title>Django 웹툰</title>
</head>
<body>
    <h1>Django 웹툰</h1>
   <p>Django 웹툰에 오신 것을 환영합니다.</p>
    <ul>
    {% for episode in episodes %}
        <li>{{ episode.title }}</li>
    {% endfor %}
    </ul>
</body>
</html>
•webtoon/views.py
from webtoon.models import *

def home(request):
    template = get_template('home.html')
    episodes = Episode.objects.all()
    variables = RequestContext(request, {
        'episodes': episodes,
    })
    output = template.render(variables)
    return HttpResponse(output)
•webtoon/templates/home.html
(...)
<li>
    <a href="{% url episode episode.comic.id episode.id %}">
        {{ episode.title }}
    </a>
</li>
(...)
•webtoon/templates/episode.html
<html>
<head>
   <title>{{ episode.title }} :: {{ episode.comic.title }} :: Django 웹툰</title>
</head>
<body>
   <h1><a href="{% url webtoon %}">Django 웹툰</a></h1>
   <h2><a href="{% url comic episode.comic.id %}">{{ episode.comic.title }}</a></h2>
   <h3>{{ episode.title }}</h3>
   <img src="{{ episode.img_file.url }}">
</body>
</html>
•webtoon/views.py

def episode(request, comic_id, episode_id):
    template = get_template('episode.html')
    episode = Episode.objects.get(id=episode_id)
    variables = RequestContext(request, {
        'episode': episode,
    })
    output = template.render(variables)
    return HttpResponse(output)
•공통된 부분을 부모 템플릿으로 생성
         • 상속 : {% extends “base.html” %}
         • 포함 : {% include “part.html” %}
         • 대체 : {% block foo %} {% endblock %}
           • {{ block.super }} 로 부모의 내용을 포함 가능
    •webtoon/templates/base.html
<html>
<head>
<title>{% block title %}Django 웹툰{% endblock %}</title>
{% block head %}{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
•webtoon/templates/episode.html
{% extends "base.html" %}
{% block title %}
   {{ episode.title }} :: {{ episode.comic.title }} :: Django 웹툰
{% endblock %}
{% block content %}
   <h1><a href="{% url webtoon %}">Django 웹툰</a></h1>
   <h2><a href="{% url comic episode.comic.id %}">{{ episode.comic.title }}</a></h2>
   <h3>{{ episode.title }}</h3>
   <img src="{{ episode.img_file.url }}">
{% endblock %}
•webtoon/templates/copyright.html
<div>모든 만화의 저작권은 각 작가에게 있습니다.</div>


    •webtoon/templates/base.html
<html>
<head>
<title>{% block title %}Django 웹툰{% endblock %}</title>
{% block head %}{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
{% include "copyright.html" %}
</body>
</html>
•더 해보기
 •/webtoon/author 뷰 구현
  • 작가 소개
  • 작가가 그린 만화 링크
 •/webtoon/comic 뷰 구현
  • 해당 만화 작가 페이지로의 링크
  • 해당 만화에 속해있는 에피소드 출력하기
 •/webtoon개선
  • 최근 만화 n개만 출력
  • 작가별 링크
Step 9. 사용자 입력



 •로그인 / 로그아웃
 •폼 처리
 •댓글 달기
•mysite/urls.py
    •기본 로그인 모듈의 경로를 모두 추가
    •로그인 : /accounts/login
    •로그아웃 : /accounts/logout
(r'^accounts/', include('django.contrib.auth.urls')),
•http://localhost:8000/accounts/login
•mysite/settings.py
     •공용 템플릿들을 보관하기 위해 디렉토리 경로 추가
TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(__file__),"templates"),
)


   •mysite/templates/registration/login.html
{% extends "base.html" %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="로그인" />
</form>
{% endblock %}
•왜 로그인 이후에 /accounts/profile 로 가는가?
•mysite/settings.py
    •LOGIN_URL : 로그인 페이지
    •LOGIN_REDIRECT_URL : 로그인 이후 갈 페이지
    •https://docs.djangoproject.com/en/1.4/topics/auth/
LOGIN_URL = '/accounts/login/'
LOGIN_REDIRECT_URL = '/webtoon/'
•로그인 여부 확인
 •in Python : if request.user.is_authenticated():
 •in Template : {% if user.is_authenticated %}
•webtoon/templates/comment.html
{% if user.is_authenticated %}
    <p>{{ user.username }} 사용자로 이름으로 댓글 달기</p>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="댓글" />
    </form>
{% else %}
    <p>
        <a href="{% url login %}">
            댓글을 달려면 로그인 해주세요.
        </a>
    </p>
{% endif %}
•webtoon/templates/episode.html
{% block content %}
    (...)
    <img src="{{ episode.img_file.url }}">
    {% include "comment.html" %}
{% endblock %}


   •webtoon/forms.py
     •https://docs.djangoproject.com/en/1.4/topics/forms/
from django import forms

class CommentForm(forms.Form):
    msg = forms.CharField(max_length=200)
•webtoon/views.py
from django.http import HttpResponseRedirect
from datetime import datetime
from webtoon.forms import *
(...)
def episode(request, comic_id, episode_id):
    template = get_template('episode.html')
    episode = Episode.objects.get(id=episode_id)

   if request.method == 'POST':
       form = CommentForm(request.POST)
       if form.is_valid():
           comment = Comment()
           comment.msg = form.cleaned_data['msg']
           comment.user = request.user
           comment.episode = episode
           comment.written_date = datetime.now()
           comment.save()
           return HttpResponseRedirect(request.get_full_path())
   else:
       form = CommentForm()
•webtoon/views.py (이전 페이지에 이어서)

(...)
    variables = RequestContext(request, {
        'episode': episode,
        'form': form,
    })
    output = template.render(variables)
    return HttpResponse(output)
•webtoon/views.py
(...)
def episode(request, comic_id, episode_id):
    # ...
    comments = Comment.objects.filter(episode=episode_id)

   variables = RequestContext(request, {
       'episode': episode,
       'form': form,
       'comments': comments,
   })
•webtoon/templates/comment.html
(...)
{% if comments %}
   댓글( 총 {{ comments|length }} 개 )
   <ul>
   {% for c in comments %}
        <li>{{ c.user.username }} : {{ c.msg }} / {{ c.written_date }}</li>
   {% endfor %}
   </ul>
{% endif %}

    •length 등, 변수에 | (pipe)로 연결되는 것은 ‘템플릿 필터’
     •템플릿에서 간단한 처리가 가능한 것들은 필터로 처리
     •https://docs.djangoproject.com/en/1.4/ref/templates/builtins/
•로그인하고 나서 다시 원래 자리로 돌아오려면?
     •next 인자로 URL 전달 - 근데 템플릿에서 현재 URL을 모른다?
   •TEMPLATE_CONTEXT_PROCESSOR
     •모든 템플릿에 전달되는 기본 값들의 집합
     •필요한 경우 컨텍스트 프로세서를 추가해서 사용하면 됨.
   •mysite/settings.py
from django.conf.global_settings
     import TEMPLATE_CONTEXT_PROCESSORS as TCP

TEMPLATE_CONTEXT_PROCESSORS = TCP + (
    'django.core.context_processors.request',
)
•webtoon/templates/comment.html
{% if user.is_authenticated %}
   (...)
{% else %}
   <p>
         <a href="{% url login %}?next={{ request.get_full_path }}">
         댓글을 달려면 로그인 해주세요.
         </a>
   </p>
{% endif %}
(...)
•어? 가입 페이지가 없잖아?! 일단 shell로 추가해보자.
(webtoon)$ python manage.py shell
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53)
(InteractiveConsole)
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user(
...                         username='anonymous',
...                         email='foo@bar.com',
...                         password='1234')
>>> user.save()
>>>
•더 해보기
 •폼을 이용한 가입 페이지 만들기
  • from django.contrib.auth.forms import UserCreationForm
  • http://www.djangobook.com/en/2.0/chapter14/
 •댓글 달기를 POST 대신 AJAX로 처리해보기
 •댓글이 많은 경우 어떻게 할 것인가?
  • /webtoon/comic_id/episode_id/comments
Step 10. 마무리



 •css 적용
 •admin 페이지에 검색 기능, 리스트 필터 등 넣어보기
 •django-debug-toolbar
•webtoon/static/css/webtoon.css
      •* { font-family: sans-serif; }
     •webtoon/static/img/django.gif
      •http://dl.dropbox.com/u/16168259/django.gif
     •webtoon/templates/base.html
html>
<head>
    <meta charset="utf-8" />
    <title>{% block title %}Django 웹툰{% endblock %}</title>
    <link rel="stylesheet" href="{{ STATIC_URL }}css/webtoon.css">
    {% block head %}{% endblock %}
</head>
<body>
    {% block content %}{% endblock %}
    {% include "copyright.html" %}
    <img src="{{ STATIC_URL }}img/django.gif">
</body>
</html>
•STATIC_ROOT / STATIC_URL
  •템플릿과 마찬가지로 앱 별 STATIC 파일과,
  •전역으로 사용할 STATIC 파일은 별도로 관리.
STATICFILES_DIRS = (
    os.path.join(os.path.dirname(__file__),"static"),
)

 •어? MEDIA 와는 다르게 왜 되는거지?
  •STATIC_URL 이 지정되어 있고,
  •settings.STATICFILES_FINDERS 에 AppDirectoriesFinder
      가 등록되어 있음.
    •MEDIA와 마찬가지로, Production에서는 사용하지 마세요.
•관리 페이지 기능 개선
    •search_fields : 검색 대상
    •ordering : 기본 정렬
   •https://docs.djangoproject.com/en/1.4/ref/contrib/admin/
   •webtoon/admin.py
class EpisodeAdmin(admin.ModelAdmin):
    list_display = ('comic', 'title', 'pub_date')
    search_fields = ['title','comic__title']
    ordering = ['-pub_date']
admin.site.register(Episode, EpisodeAdmin)
•Django debug toolbar
       •http://blog.naver.com/ez_/140162876100
(webtoon)$ pip install django-debug-toolbar

MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
INSTALLED_APPS += ('debug_toolbar',)
INTERNAL_IPS = ('127.0.0.1',)
DEBUG_TOOLBAR_PANELS = (
    'debug_toolbar.panels.version.VersionDebugPanel',
    'debug_toolbar.panels.timer.TimerDebugPanel',
    'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
    'debug_toolbar.panels.headers.HeaderDebugPanel',
    'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
    'debug_toolbar.panels.template.TemplateDebugPanel',
    'debug_toolbar.panels.sql.SQLDebugPanel',
    'debug_toolbar.panels.signals.SignalDebugPanel',
    'debug_toolbar.panels.logger.LoggingPanel',
    'debug_toolbar.panels.profiling.ProfilingDebugPanel',
)
집에서 더 해볼만한 것


 •South 를 통해 기존 모델 변경해보기
  •http://jcstyle.tistory.com/entry/django-migration-tool-
    South-%EC%9E%91%EC%97%85%EA%B8%B0

 •별점 주기 기능 추가
  •Rating Model 을 추가하는 것으로 시작.
참여한 분들에게 바라는 점


•오늘 실습을 끝까지 진행하지 못했어도,
 •환경은 구축되었으므로, 나머지를 끝까지 진행해주세요.

•주변에 많이 소개해주세요.
 •스마트스터디는 이상한 회사다!
 •블로그 등으로 써주시고, 저희 페이스북 페이지에 알려주세요 :D
모두 수고하셨습니다!

Más contenido relacionado

La actualidad más candente

Resource Handling in Spring MVC
Resource Handling in Spring MVCResource Handling in Spring MVC
Resource Handling in Spring MVCArawn Park
 
spring.io를 통해 배우는 spring 개발사례
spring.io를 통해 배우는 spring 개발사례spring.io를 통해 배우는 spring 개발사례
spring.io를 통해 배우는 spring 개발사례Daehwan Lee
 
진짜기초 Node.js
진짜기초 Node.js진짜기초 Node.js
진짜기초 Node.jsWoo Jin Kim
 
Node.js + Websocket 삽질기
Node.js + Websocket 삽질기Node.js + Websocket 삽질기
Node.js + Websocket 삽질기Paprikhan
 
Javascript everywhere - Node.js | Devon 2012
Javascript everywhere - Node.js | Devon 2012Javascript everywhere - Node.js | Devon 2012
Javascript everywhere - Node.js | Devon 2012Daum DNA
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs기동 이
 
Python Recipes for django girls seoul
Python Recipes for django girls seoulPython Recipes for django girls seoul
Python Recipes for django girls seoulJoeun Park
 
Node.js의 도입과 활용
Node.js의 도입과 활용Node.js의 도입과 활용
Node.js의 도입과 활용Jin wook
 
오픈소스를 활용한 Batch_처리_플랫폼_공유
오픈소스를 활용한 Batch_처리_플랫폼_공유오픈소스를 활용한 Batch_처리_플랫폼_공유
오픈소스를 활용한 Batch_처리_플랫폼_공유knight1128
 
Node.js
Node.jsNode.js
Node.jsymtech
 
오픈 소스를 활용한 게임 배치 플랫폼 개선 사례
오픈 소스를 활용한 게임 배치 플랫폼 개선 사례오픈 소스를 활용한 게임 배치 플랫폼 개선 사례
오픈 소스를 활용한 게임 배치 플랫폼 개선 사례형석 김
 
20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debugging20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debuggingJongwon Han
 
Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나JeongHun Byeon
 
React 튜토리얼 2차시
React 튜토리얼 2차시React 튜토리얼 2차시
React 튜토리얼 2차시태현 김
 
20131217 html5
20131217 html520131217 html5
20131217 html5DK Lee
 
백기선의 스프링 부트
백기선의 스프링 부트백기선의 스프링 부트
백기선의 스프링 부트Keesun Baik
 
스프링 부트와 로깅
스프링 부트와 로깅스프링 부트와 로깅
스프링 부트와 로깅Keesun Baik
 
Springcamp spring boot intro
Springcamp spring boot introSpringcamp spring boot intro
Springcamp spring boot introJae-il Lee
 

La actualidad más candente (20)

Light Tutorial Django
Light Tutorial DjangoLight Tutorial Django
Light Tutorial Django
 
Resource Handling in Spring MVC
Resource Handling in Spring MVCResource Handling in Spring MVC
Resource Handling in Spring MVC
 
spring.io를 통해 배우는 spring 개발사례
spring.io를 통해 배우는 spring 개발사례spring.io를 통해 배우는 spring 개발사례
spring.io를 통해 배우는 spring 개발사례
 
진짜기초 Node.js
진짜기초 Node.js진짜기초 Node.js
진짜기초 Node.js
 
Node.js + Websocket 삽질기
Node.js + Websocket 삽질기Node.js + Websocket 삽질기
Node.js + Websocket 삽질기
 
Javascript everywhere - Node.js | Devon 2012
Javascript everywhere - Node.js | Devon 2012Javascript everywhere - Node.js | Devon 2012
Javascript everywhere - Node.js | Devon 2012
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
 
Python Recipes for django girls seoul
Python Recipes for django girls seoulPython Recipes for django girls seoul
Python Recipes for django girls seoul
 
Node.js의 도입과 활용
Node.js의 도입과 활용Node.js의 도입과 활용
Node.js의 도입과 활용
 
오픈소스를 활용한 Batch_처리_플랫폼_공유
오픈소스를 활용한 Batch_처리_플랫폼_공유오픈소스를 활용한 Batch_처리_플랫폼_공유
오픈소스를 활용한 Batch_처리_플랫폼_공유
 
Node.js
Node.jsNode.js
Node.js
 
오픈 소스를 활용한 게임 배치 플랫폼 개선 사례
오픈 소스를 활용한 게임 배치 플랫폼 개선 사례오픈 소스를 활용한 게임 배치 플랫폼 개선 사례
오픈 소스를 활용한 게임 배치 플랫폼 개선 사례
 
20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debugging20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debugging
 
Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나
 
React 튜토리얼 2차시
React 튜토리얼 2차시React 튜토리얼 2차시
React 튜토리얼 2차시
 
20131217 html5
20131217 html520131217 html5
20131217 html5
 
백기선의 스프링 부트
백기선의 스프링 부트백기선의 스프링 부트
백기선의 스프링 부트
 
스프링 부트와 로깅
스프링 부트와 로깅스프링 부트와 로깅
스프링 부트와 로깅
 
Gulp 입문
Gulp 입문 Gulp 입문
Gulp 입문
 
Springcamp spring boot intro
Springcamp spring boot introSpringcamp spring boot intro
Springcamp spring boot intro
 

Destacado

Cassandra + Spark + Elk
Cassandra + Spark + ElkCassandra + Spark + Elk
Cassandra + Spark + ElkVasil Remeniuk
 
Elassandra: Elasticsearch as a Cassandra Secondary Index (Rémi Trouville, Vin...
Elassandra: Elasticsearch as a Cassandra Secondary Index (Rémi Trouville, Vin...Elassandra: Elasticsearch as a Cassandra Secondary Index (Rémi Trouville, Vin...
Elassandra: Elasticsearch as a Cassandra Secondary Index (Rémi Trouville, Vin...DataStax
 
How We Used Cassandra/Solr to Build Real-Time Analytics Platform
How We Used Cassandra/Solr to Build Real-Time Analytics PlatformHow We Used Cassandra/Solr to Build Real-Time Analytics Platform
How We Used Cassandra/Solr to Build Real-Time Analytics PlatformDataStax Academy
 
그런데 스타트업이 뭐더라
그런데 스타트업이 뭐더라그런데 스타트업이 뭐더라
그런데 스타트업이 뭐더라Hyun-woo Park
 
Spark to Production @Windward
Spark to Production @WindwardSpark to Production @Windward
Spark to Production @WindwardDemi Ben-Ari
 
Solr & Cassandra: Searching Cassandra with DataStax Enterprise
Solr & Cassandra: Searching Cassandra with DataStax EnterpriseSolr & Cassandra: Searching Cassandra with DataStax Enterprise
Solr & Cassandra: Searching Cassandra with DataStax EnterpriseDataStax Academy
 
2016년 10월 파이썬 사용자 모임 오프닝
2016년 10월 파이썬 사용자 모임 오프닝2016년 10월 파이썬 사용자 모임 오프닝
2016년 10월 파이썬 사용자 모임 오프닝Hyun-woo Park
 
Stratio's Cassandra Lucene index: Geospatial Use Cases (Andrés de la Peña & J...
Stratio's Cassandra Lucene index: Geospatial Use Cases (Andrés de la Peña & J...Stratio's Cassandra Lucene index: Geospatial Use Cases (Andrés de la Peña & J...
Stratio's Cassandra Lucene index: Geospatial Use Cases (Andrés de la Peña & J...DataStax
 
Tox, Travis 그리고 Codecov 로 오픈소스 생태계에 기여하기
Tox, Travis 그리고 Codecov 로 오픈소스 생태계에 기여하기Tox, Travis 그리고 Codecov 로 오픈소스 생태계에 기여하기
Tox, Travis 그리고 Codecov 로 오픈소스 생태계에 기여하기Hyun-woo Park
 
Continuous Deployment: Beyond Continuous Delivery
Continuous Deployment: Beyond Continuous DeliveryContinuous Deployment: Beyond Continuous Delivery
Continuous Deployment: Beyond Continuous DeliveryTimothy Fitz
 
A Cassandra + Solr + Spark Love Triangle Using DataStax Enterprise
A Cassandra + Solr + Spark Love Triangle Using DataStax EnterpriseA Cassandra + Solr + Spark Love Triangle Using DataStax Enterprise
A Cassandra + Solr + Spark Love Triangle Using DataStax EnterprisePatrick McFadin
 
Py conkr 20150829_docker-python
Py conkr 20150829_docker-pythonPy conkr 20150829_docker-python
Py conkr 20150829_docker-pythonEric Ahn
 
파이썬 삼총사 : Tox, Travis 그리고 Coveralls
파이썬 삼총사 : Tox, Travis 그리고 Coveralls파이썬 삼총사 : Tox, Travis 그리고 Coveralls
파이썬 삼총사 : Tox, Travis 그리고 CoverallsHyun-woo Park
 
Using Event-Driven Architectures with Cassandra
Using Event-Driven Architectures with CassandraUsing Event-Driven Architectures with Cassandra
Using Event-Driven Architectures with CassandraDataStax Academy
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseDataStax Academy
 
Advanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraAdvanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraDataStax Academy
 
[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅NAVER D2
 
[스마트스터디] 재택근무 잘 하고 있어요
[스마트스터디] 재택근무 잘 하고 있어요[스마트스터디] 재택근무 잘 하고 있어요
[스마트스터디] 재택근무 잘 하고 있어요Hyekyoung Yun
 
WE HAVE ALMOST NOTHING, SMARTSTUDY
WE HAVE ALMOST NOTHING, SMARTSTUDYWE HAVE ALMOST NOTHING, SMARTSTUDY
WE HAVE ALMOST NOTHING, SMARTSTUDYHyun-woo Park
 
간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기Kyoung Up Jung
 

Destacado (20)

Cassandra + Spark + Elk
Cassandra + Spark + ElkCassandra + Spark + Elk
Cassandra + Spark + Elk
 
Elassandra: Elasticsearch as a Cassandra Secondary Index (Rémi Trouville, Vin...
Elassandra: Elasticsearch as a Cassandra Secondary Index (Rémi Trouville, Vin...Elassandra: Elasticsearch as a Cassandra Secondary Index (Rémi Trouville, Vin...
Elassandra: Elasticsearch as a Cassandra Secondary Index (Rémi Trouville, Vin...
 
How We Used Cassandra/Solr to Build Real-Time Analytics Platform
How We Used Cassandra/Solr to Build Real-Time Analytics PlatformHow We Used Cassandra/Solr to Build Real-Time Analytics Platform
How We Used Cassandra/Solr to Build Real-Time Analytics Platform
 
그런데 스타트업이 뭐더라
그런데 스타트업이 뭐더라그런데 스타트업이 뭐더라
그런데 스타트업이 뭐더라
 
Spark to Production @Windward
Spark to Production @WindwardSpark to Production @Windward
Spark to Production @Windward
 
Solr & Cassandra: Searching Cassandra with DataStax Enterprise
Solr & Cassandra: Searching Cassandra with DataStax EnterpriseSolr & Cassandra: Searching Cassandra with DataStax Enterprise
Solr & Cassandra: Searching Cassandra with DataStax Enterprise
 
2016년 10월 파이썬 사용자 모임 오프닝
2016년 10월 파이썬 사용자 모임 오프닝2016년 10월 파이썬 사용자 모임 오프닝
2016년 10월 파이썬 사용자 모임 오프닝
 
Stratio's Cassandra Lucene index: Geospatial Use Cases (Andrés de la Peña & J...
Stratio's Cassandra Lucene index: Geospatial Use Cases (Andrés de la Peña & J...Stratio's Cassandra Lucene index: Geospatial Use Cases (Andrés de la Peña & J...
Stratio's Cassandra Lucene index: Geospatial Use Cases (Andrés de la Peña & J...
 
Tox, Travis 그리고 Codecov 로 오픈소스 생태계에 기여하기
Tox, Travis 그리고 Codecov 로 오픈소스 생태계에 기여하기Tox, Travis 그리고 Codecov 로 오픈소스 생태계에 기여하기
Tox, Travis 그리고 Codecov 로 오픈소스 생태계에 기여하기
 
Continuous Deployment: Beyond Continuous Delivery
Continuous Deployment: Beyond Continuous DeliveryContinuous Deployment: Beyond Continuous Delivery
Continuous Deployment: Beyond Continuous Delivery
 
A Cassandra + Solr + Spark Love Triangle Using DataStax Enterprise
A Cassandra + Solr + Spark Love Triangle Using DataStax EnterpriseA Cassandra + Solr + Spark Love Triangle Using DataStax Enterprise
A Cassandra + Solr + Spark Love Triangle Using DataStax Enterprise
 
Py conkr 20150829_docker-python
Py conkr 20150829_docker-pythonPy conkr 20150829_docker-python
Py conkr 20150829_docker-python
 
파이썬 삼총사 : Tox, Travis 그리고 Coveralls
파이썬 삼총사 : Tox, Travis 그리고 Coveralls파이썬 삼총사 : Tox, Travis 그리고 Coveralls
파이썬 삼총사 : Tox, Travis 그리고 Coveralls
 
Using Event-Driven Architectures with Cassandra
Using Event-Driven Architectures with CassandraUsing Event-Driven Architectures with Cassandra
Using Event-Driven Architectures with Cassandra
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax Enterprise
 
Advanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraAdvanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache Cassandra
 
[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅
 
[스마트스터디] 재택근무 잘 하고 있어요
[스마트스터디] 재택근무 잘 하고 있어요[스마트스터디] 재택근무 잘 하고 있어요
[스마트스터디] 재택근무 잘 하고 있어요
 
WE HAVE ALMOST NOTHING, SMARTSTUDY
WE HAVE ALMOST NOTHING, SMARTSTUDYWE HAVE ALMOST NOTHING, SMARTSTUDY
WE HAVE ALMOST NOTHING, SMARTSTUDY
 
간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기
 

Similar a SMARTSTUDY Django 오픈 세션 2012-08

구글 앱 엔진을 이용한 소셜네트워크게임(SNG) 개발(2)
구글 앱 엔진을 이용한 소셜네트워크게임(SNG) 개발(2)구글 앱 엔진을 이용한 소셜네트워크게임(SNG) 개발(2)
구글 앱 엔진을 이용한 소셜네트워크게임(SNG) 개발(2)mosaicnet
 
W3C HTML5 Conference 2015 - NAVER 웹 기술 및 환경 전망
W3C HTML5 Conference 2015 - NAVER 웹 기술 및 환경 전망W3C HTML5 Conference 2015 - NAVER 웹 기술 및 환경 전망
W3C HTML5 Conference 2015 - NAVER 웹 기술 및 환경 전망NAVER Engineering
 
Open source apm scouter를 통한 관제 관리 jadecross 정환열 수석
Open source apm scouter를 통한 관제  관리 jadecross 정환열 수석Open source apm scouter를 통한 관제  관리 jadecross 정환열 수석
Open source apm scouter를 통한 관제 관리 jadecross 정환열 수석uEngine Solutions
 
모바일 Rpg 게임서버 제작
모바일 Rpg 게임서버 제작모바일 Rpg 게임서버 제작
모바일 Rpg 게임서버 제작기환 천
 
Accelerate spring boot application with apache ignite
Accelerate spring boot application with apache igniteAccelerate spring boot application with apache ignite
Accelerate spring boot application with apache igniteYEON BOK LEE
 
세션3 node.js의 의미와 자바의 대안
세션3 node.js의 의미와 자바의 대안세션3 node.js의 의미와 자바의 대안
세션3 node.js의 의미와 자바의 대안Lee Ji Eun
 
NAVER의 웹/HTML5환경 대응 현황
NAVER의 웹/HTML5환경 대응 현황NAVER의 웹/HTML5환경 대응 현황
NAVER의 웹/HTML5환경 대응 현황NAVER Engineering
 
MEAN Stack 기반 모바일 서비스 개발 overview
MEAN Stack 기반 모바일 서비스 개발 overviewMEAN Stack 기반 모바일 서비스 개발 overview
MEAN Stack 기반 모바일 서비스 개발 overview민태 김
 
Introduction to Apache Tajo
Introduction to Apache TajoIntroduction to Apache Tajo
Introduction to Apache TajoGruter
 
[C5]deview 2012 nodejs
[C5]deview 2012 nodejs[C5]deview 2012 nodejs
[C5]deview 2012 nodejsNAVER D2
 
마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기Jaewoo Ahn
 
Web app 개발 방법론
Web app 개발 방법론Web app 개발 방법론
Web app 개발 방법론Sang Seok Lim
 
스타트업사례로 본 로그 데이터분석 : Tajo on AWS
스타트업사례로 본 로그 데이터분석 : Tajo on AWS스타트업사례로 본 로그 데이터분석 : Tajo on AWS
스타트업사례로 본 로그 데이터분석 : Tajo on AWSGruter
 
02.JBOSS EAP7(FOR CONTAINER/CLOUD)
02.JBOSS EAP7(FOR CONTAINER/CLOUD)02.JBOSS EAP7(FOR CONTAINER/CLOUD)
02.JBOSS EAP7(FOR CONTAINER/CLOUD)Opennaru, inc.
 
[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How To[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How ToJi-Woong Choi
 
주니어 개발자의 서버 로그 관리 개선기
주니어 개발자의 서버 로그 관리 개선기주니어 개발자의 서버 로그 관리 개선기
주니어 개발자의 서버 로그 관리 개선기Yeonhee Kim
 
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...문기 박
 
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기YoungSu Son
 

Similar a SMARTSTUDY Django 오픈 세션 2012-08 (20)

구글 앱 엔진을 이용한 소셜네트워크게임(SNG) 개발(2)
구글 앱 엔진을 이용한 소셜네트워크게임(SNG) 개발(2)구글 앱 엔진을 이용한 소셜네트워크게임(SNG) 개발(2)
구글 앱 엔진을 이용한 소셜네트워크게임(SNG) 개발(2)
 
N02 gae v1.1_20110220
N02 gae v1.1_20110220N02 gae v1.1_20110220
N02 gae v1.1_20110220
 
W3C HTML5 Conference 2015 - NAVER 웹 기술 및 환경 전망
W3C HTML5 Conference 2015 - NAVER 웹 기술 및 환경 전망W3C HTML5 Conference 2015 - NAVER 웹 기술 및 환경 전망
W3C HTML5 Conference 2015 - NAVER 웹 기술 및 환경 전망
 
Open source apm scouter를 통한 관제 관리 jadecross 정환열 수석
Open source apm scouter를 통한 관제  관리 jadecross 정환열 수석Open source apm scouter를 통한 관제  관리 jadecross 정환열 수석
Open source apm scouter를 통한 관제 관리 jadecross 정환열 수석
 
모바일 Rpg 게임서버 제작
모바일 Rpg 게임서버 제작모바일 Rpg 게임서버 제작
모바일 Rpg 게임서버 제작
 
Accelerate spring boot application with apache ignite
Accelerate spring boot application with apache igniteAccelerate spring boot application with apache ignite
Accelerate spring boot application with apache ignite
 
세션3 node.js의 의미와 자바의 대안
세션3 node.js의 의미와 자바의 대안세션3 node.js의 의미와 자바의 대안
세션3 node.js의 의미와 자바의 대안
 
NAVER의 웹/HTML5환경 대응 현황
NAVER의 웹/HTML5환경 대응 현황NAVER의 웹/HTML5환경 대응 현황
NAVER의 웹/HTML5환경 대응 현황
 
MEAN Stack 기반 모바일 서비스 개발 overview
MEAN Stack 기반 모바일 서비스 개발 overviewMEAN Stack 기반 모바일 서비스 개발 overview
MEAN Stack 기반 모바일 서비스 개발 overview
 
Introduction to Apache Tajo
Introduction to Apache TajoIntroduction to Apache Tajo
Introduction to Apache Tajo
 
[C5]deview 2012 nodejs
[C5]deview 2012 nodejs[C5]deview 2012 nodejs
[C5]deview 2012 nodejs
 
3장
3장3장
3장
 
마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기
 
Web app 개발 방법론
Web app 개발 방법론Web app 개발 방법론
Web app 개발 방법론
 
스타트업사례로 본 로그 데이터분석 : Tajo on AWS
스타트업사례로 본 로그 데이터분석 : Tajo on AWS스타트업사례로 본 로그 데이터분석 : Tajo on AWS
스타트업사례로 본 로그 데이터분석 : Tajo on AWS
 
02.JBOSS EAP7(FOR CONTAINER/CLOUD)
02.JBOSS EAP7(FOR CONTAINER/CLOUD)02.JBOSS EAP7(FOR CONTAINER/CLOUD)
02.JBOSS EAP7(FOR CONTAINER/CLOUD)
 
[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How To[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How To
 
주니어 개발자의 서버 로그 관리 개선기
주니어 개발자의 서버 로그 관리 개선기주니어 개발자의 서버 로그 관리 개선기
주니어 개발자의 서버 로그 관리 개선기
 
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
 
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
 

Más de Hyun-woo Park

2019년에 기술 문서를 번역하는 기분
2019년에 기술 문서를 번역하는 기분2019년에 기술 문서를 번역하는 기분
2019년에 기술 문서를 번역하는 기분Hyun-woo Park
 
파이콘 한국 2017 키노트 : Back to the Basic
파이콘 한국 2017 키노트 : Back to the Basic파이콘 한국 2017 키노트 : Back to the Basic
파이콘 한국 2017 키노트 : Back to the BasicHyun-woo Park
 
파이콘 한국 2015 디자인 후기
파이콘 한국 2015 디자인 후기파이콘 한국 2015 디자인 후기
파이콘 한국 2015 디자인 후기Hyun-woo Park
 
Dive into OpenSource
Dive into OpenSourceDive into OpenSource
Dive into OpenSourceHyun-woo Park
 
그릇된 팬심의 어긋난 결말
그릇된 팬심의 어긋난 결말그릇된 팬심의 어긋난 결말
그릇된 팬심의 어긋난 결말Hyun-woo Park
 
스타트업에서 기술책임자로 살아가기
스타트업에서 기술책임자로 살아가기스타트업에서 기술책임자로 살아가기
스타트업에서 기술책임자로 살아가기Hyun-woo Park
 
Using CloudFront and S3 at SMARTSTUDY
Using CloudFront and S3 at SMARTSTUDYUsing CloudFront and S3 at SMARTSTUDY
Using CloudFront and S3 at SMARTSTUDYHyun-woo Park
 
The MongoDB Strikes Back / MongoDB 의 역습
The MongoDB Strikes Back / MongoDB 의 역습The MongoDB Strikes Back / MongoDB 의 역습
The MongoDB Strikes Back / MongoDB 의 역습Hyun-woo Park
 
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY (English)
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY (English)WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY (English)
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY (English)Hyun-woo Park
 
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDYWHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDYHyun-woo Park
 
Using AWS CloudFront with S3 at SMARTSTUDY
Using AWS CloudFront with S3 at SMARTSTUDYUsing AWS CloudFront with S3 at SMARTSTUDY
Using AWS CloudFront with S3 at SMARTSTUDYHyun-woo Park
 
넝쿨째 굴러온 김성모
넝쿨째 굴러온 김성모넝쿨째 굴러온 김성모
넝쿨째 굴러온 김성모Hyun-woo Park
 

Más de Hyun-woo Park (12)

2019년에 기술 문서를 번역하는 기분
2019년에 기술 문서를 번역하는 기분2019년에 기술 문서를 번역하는 기분
2019년에 기술 문서를 번역하는 기분
 
파이콘 한국 2017 키노트 : Back to the Basic
파이콘 한국 2017 키노트 : Back to the Basic파이콘 한국 2017 키노트 : Back to the Basic
파이콘 한국 2017 키노트 : Back to the Basic
 
파이콘 한국 2015 디자인 후기
파이콘 한국 2015 디자인 후기파이콘 한국 2015 디자인 후기
파이콘 한국 2015 디자인 후기
 
Dive into OpenSource
Dive into OpenSourceDive into OpenSource
Dive into OpenSource
 
그릇된 팬심의 어긋난 결말
그릇된 팬심의 어긋난 결말그릇된 팬심의 어긋난 결말
그릇된 팬심의 어긋난 결말
 
스타트업에서 기술책임자로 살아가기
스타트업에서 기술책임자로 살아가기스타트업에서 기술책임자로 살아가기
스타트업에서 기술책임자로 살아가기
 
Using CloudFront and S3 at SMARTSTUDY
Using CloudFront and S3 at SMARTSTUDYUsing CloudFront and S3 at SMARTSTUDY
Using CloudFront and S3 at SMARTSTUDY
 
The MongoDB Strikes Back / MongoDB 의 역습
The MongoDB Strikes Back / MongoDB 의 역습The MongoDB Strikes Back / MongoDB 의 역습
The MongoDB Strikes Back / MongoDB 의 역습
 
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY (English)
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY (English)WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY (English)
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY (English)
 
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDYWHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY
WHAT / WHY / HOW WE’RE ENGINEERING AT SMARTSTUDY
 
Using AWS CloudFront with S3 at SMARTSTUDY
Using AWS CloudFront with S3 at SMARTSTUDYUsing AWS CloudFront with S3 at SMARTSTUDY
Using AWS CloudFront with S3 at SMARTSTUDY
 
넝쿨째 굴러온 김성모
넝쿨째 굴러온 김성모넝쿨째 굴러온 김성모
넝쿨째 굴러온 김성모
 

SMARTSTUDY Django 오픈 세션 2012-08

  • 1. Django In Action This session brought to you by SMARTSTUDY
  • 2. 박현우 @lqez 2001-2006 NHN 2007-2010 NPLUTO 2010-현재 SMARTSTUDY 게임 개발자로 시작, 10년간 업계에서 구르다 지금은 걍 카페코딩 좋아하는 SCV.
  • 3. 스마트스터디 2010년 설립, 삼성출판사의 자회사 게임 업계에서 실컷 굴러본 경력! + 실력과 열정 넘치는 멋진 신입! 유아동 애플리케이션 + 만화, 동영상, 게임이 주력 사업. 양질의 콘텐츠를 수급하여, 좋은 서비스를 만드는 것이 목표!
  • 4. OK, 회사 소개는 거기까지.
  • 5. Session A •Django 소개 •장단점 •우리는 왜? •직접 경험하기
  • 6. 역사 • Lawrence.com PHP 기반 웹사이트 유지보수를 위해.1 •개발자가 좋아하던 기타리스트인 Django Reinhardt 의 이름을 따서 지음. [1] http://www.quora.com/What-is-the-history-of-the-Django-web-framework
  • 7. 특징 • Full Stack Framework •웹 페이지를 만들기 위한 대부분의 요소가 포함되어 있음. • HTTP Request / Response 처리, URL 패칭 • 템플릿 엔진 • ORM •Lawrence.com 은 언론 / 뉴스 사이트. •개발 당시 부르던 내부 이름은 ‘The CMS’. •따라서, Admin 프레임워크가 잘 갖춰져 있다.
  • 8. 역할 HTTP Request http://foo.com Parsing Query Users Web Servers Web Application Data HTTP Response HTML Page QuerySet JSON Result
  • 9. 역할 HTTP Request http://foo.com ParsingURL ORMQuery Dispatcher Users Web Servers WSGI Web Application Data Template HTTP Response HTML Page Engine QuerySet Serializer JSON Result Django
  • 10. 역할, 그리고 Sessions Authentication Cache Backend & Cookies & Authorization Error HTTP Request Database http://foo.com Reporting ParsingURL ORMQuery Router Dispatcher Users Web Servers WSGI Admin Page Web Application Aggregation Data Template HTTP Response HTML Page Engine QuerySetSQL Serializer RAW Testing JSON Result Internalization Security Forms Logging & Localization Django
  • 11. ... 거기에 더해 http://www.djangopackages.com/
  • 12. 그래서, Django is Full Stack Web Framework
  • 13. 그런데, Sessions Authentication Cache Backend & Cookies & Authorization Error HTTP Request Database http://foo.com Reporting ParsingURL SQL Query ORM Router Dispatcher Alchemy Users Web Servers WSGI Admin Page Web Application Aggregation Data Template HTTP Response BDD HTML Page2 Jinja Engine QuerySetSQL Serializer RAW Testing Toolkit JSON Result Internalization Security Forms Logging & Localization Django
  • 14. 그런데, Sessions Authentication Cache Backend & Cookies & Authorization Error HTTP Request Database http://foo.com Reporting ParsingURL SQL Query ORM Router Dispatcher Alchemy Users Web Servers WSGI Admin Page Web Application Aggregation Data HTTP Response FAILEDTemplate QuerySet BDD Testing HTML Page2 Jinja Engine Serializer RAW SQL Toolkit JSON Result Internalization Security Forms Logging & Localization Django
  • 15. 대안은? •Werkzeug • The Python WSGI Utility Library • HTTP Request parsing / Response objects • URL Dispatching •Flask • a micro-framework for Python based on Werkzeug • Jinja 2 / Unit test / RESTful dispatching / Cookies • 국내에선, • 패션 SNS - StyleSha.re • http://engineering.stylesha.re/post/28761152299/styleshare-service-stack • 모바일 소셜 포인트 카드 - DoDo / Spoqa 등이 사용중. • http://spoqa.github.com/2012/01/16/wsgi-and-flask.html
  • 16. 장단점 • Full Stack Framework •장점 : 하나만 배우면 된다. •단점 : 하나라도 제대로 이해하고 쓰기는 어렵다. • Micro Framework •장점 : 레고를 조립하듯 입맛대로 서비스를 구성할 수 있다. •단점 : 뭐든지 찾아써야 한다.
  • 17. 우리는 왜 Django를 선택했나. •PHP로 더 이상 심각한 웹 개발을 하고 싶지 않다. • 딱히 싫어하는건 아니지만... •왜 Python을? • 예전부터 써봤었고, • 각종 스크립트도 작성해서 쓰고 있었기에, • 웹 개발을 위해 별도로 Ruby나 Perl 등을 배우고 싶진 않다! •하지만 웹 개발 전문가라 부를 사람이 없었음. •와중에 10분만에 Django로 블로그 만들기 등을 보게 됨. • http://www.lightbird.net/dbe/blog.html
  • 19. 아... 안돼! •아쉬운 점 •생각보다 정적 페이지 구성이 없음. •애초에 Heavy AJAX 형태의 웹 서비스를 위한 구조가 아님. • Paginator 같은 건 당연히 필요 없음. •폼 처리가 거의 없다보니 매력 감소. •기본 제공 관리 페이지가 우리에게 그리 쓸만하지 않음. • User가 10만명이 넘어가는데, 해당 모델을 포함한 관리 페이지에서 10만개의 OPTION 태그로 그냥 출력해버리는 대범함... 당연히 엄청 느림.
  • 20. Django 장점 정리 1. 어쨌거나 웹 개발의 껍질만 배우고도 시작할 수 있다. 2. 한국어/한글로 된 도서도 있다! (...) 3. 각종 추가 모듈의 도움으로 간편하게 기능 확장! 4. 가볍게 데이터를 읽고 쓰기엔 기본 ORM도 나쁘지 않다. 5. 기본 템플릿 엔진도 그럭저럭 쓸만함. 6. 썩어도 준치, 없는 것보단 나은 기본 관리 페이지.
  • 21. Django 장점 정리 1. 어쨌거나 웹 개발의 껍질만 배우고도시작 수 있다. 시작할 한국어 2. 한국어/한글로 된 도서도 있다! (...) 추가 모듈 3. 각종 추가 모듈의 도움으로 간편하게 기능 확장! 4. 가볍게 데이터를 읽고 쓰기엔기본ORM도 나쁘지 않다. 기본 ORM 5.기본 템플릿 그럭저럭 쓸만함. 기본 템플릿 엔진도 6. 썩어도 준치, 없는 것보단 나은 관리 페이지 기본 관리 페이지.
  • 22. 하지만 여러분에겐, •먼저 삽질한 스마트스터디가 있습니다. 미약하나마 •오늘 실습이 선택에 도움이 되길 바랍니다. •페이스북 그룹도 있더군요. • https://www.facebook.com/groups/django/ • 꽤 활발합니다! •IRC도 있습니다. • #django / irc.ozinger.org • 하루 종일 아무도 말 안합니다...
  • 23. Session B 어쨌든 우리는 오늘 웹툰을 만들껍니다. 웹툰 화면은 네이버 웹툰(http://m.comic.naver.com)에서 발췌.
  • 24. ...물론 현실은, 대략 이 정도...? 모든 이미지는 http://www.projectcartoon.com/ 에서 발췌.
  • 25. Step 0. 알고가기 •터미널 / 쉘에서 직접 실행하기 ( 초록색 배경 ) > dir $ ls •소스 수정 ( 검은색 배경 ) • 대부분의 경우 덮어쓰기 보다는 부분 수정이 많으니 주의해주세요. # 이미 입력되어 있던 소스 - 하얀색 from webtoon.models import * (...) - 생략된 부분 # 새로 입력해야 하는 소스 - 노란색 def home(request): return HttpResponse(output)
  • 26. •Python은 들여쓰기(Indentation)을 탭, 또는 빈칸으로 합니다. •하나의 소스 파일 내에서는 같은 들여쓰기 규칙을 유지합니다. •섞어 쓰면 문법 오류가 발생. •실습에서 .py / .html 파일은 모두 UTF-8 인코딩을 사용합니다. •.py 에서도 한글을 사용하려면 아래 내용을 첫 줄에 넣습니다. # -*- coding: utf-8 -*-
  • 27. Step 1. 준비 •Python •setuptools / pip •VirtualEnv / VirtualEnvWrapper •소개 : http://blog.naver.com/ez_/140138625021
  • 28. •Windows •기본으로 Python이 없으니, Python부터 설치합니다. 2.7을 선택해주세요. • http://python.org/download/ • 인스톨러를 통해 편리하게 설치할 수 있습니다. • 환경 변수 PATH에 아래 경로를 추가합니다. • C:Python27;C:Python27Scripts; • 환경 변수 PYTHONHOME을 지정합니다. • C:Python27 • http://pypi.python.org/pypi/setuptools • 32bit : http://pypi.python.org/packages/2.7/s/setuptools/ setuptools-0.6c11.win32-py2.7.exe 를 다운받아 실행. • 64bit : http://peak.telecommunity.com/dist/ez_setup.py 를 다운받 아 python ez_setup.py 로 실행.
  • 29. •Windows (이어서 계속) > easy_install pip > pip install virtualenvwrapper-win •OS X / Linux $ sudo easy_install pip $ sudo pip install virtualenvwrapper $ source /usr/local/bin/virtualenvwrapper.sh •OS X 에서 distutils 오류 발생시, 아래 명령어 수행. $ sudo touch /System/Library/Frameworks/Python.framework/ Versions/2.7/lib/python2.7/distutils/__init__.py http://stackoverflow.com/questions/3129852/python-cant-locate-distutils-path-on-mac-osx
  • 30. •OS X / Linux 에서 ~/.profile 에 아래 내용 추가 source /usr/local/bin/virtualenvwrapper.sh # 가상 환경 위치를 바꾸고 싶으면 WORKON_HOME 수정 # 기본 위치는 ~/.virtualenvs export WORKON_HOME=~/VirtualEnvs
  • 31. Step 2. Django 설치 •mkvirtualenv •workon / deactivate •pip install django
  • 32. $ mkvirtualenv webtoon New python executable in webtoon/bin/python Installing setuptools............done. Installing pip...............done. (...) (webtoon)$ deactiviate $ workon (...이미 생성된 가상 환경들의 목록...) $ workon webtoon (webtoon)$
  • 33. (webtoon)$ pip install django Downloading/unpacking django Downloading Django-1.4.1.tar.gz (7.7Mb): ... Running setup.py egg_info for package django Installing collected packages: django Running setup.py install for django (...) Successfully installed django Cleaning up... (webtoon)$
  • 34. •잘 설치되었는지 확인! (webtoon)$ python Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) >>> import django >>> django.VERSION (1, 4, 1, 'final', 0) >>>
  • 35. •Windows •copy <홈 디렉토리>EnvsLibsite-packagesdjangobin django-admin.py c:Python27Scripts • 위와 같이 미리 복사해주시면 편합니다. • 보통 홈 디렉토리는 ‘C:Document and settings사용자 이름’
  • 36.
  • 37. Step 3. 드디어 시작! •django-admin.py startproject mysite •python manage.py runserver •https://docs.djangoproject.com/en/1.4/intro/
  • 38. (webtoon)$ django-admin.py (...) (webtoon)$ django-admin.py startproject mysite (webtoon)$ cd mysite/ (webtoon)$ ls manage.py mysite (webtoon)$ python manage.py runserver Validating models... 0 errors found Django version 1.4.1, using settings 'mysite.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. •Windows 의 경우, •python c:Python27Scriptsdjango-admin.py ...
  • 39.
  • 40. Step 4. 웹툰 시작 •django-admin.py startapp webtoon •settings.py 의 INSTALLED_APP 에 추가 •urls.py 에 뷰 등록
  • 41. (webtoon)$ python manage.py startapp webtoon (webtoon)$ ls manage.py mysite webtoon (webtoon)$ •App 을 project 와 같은 위치에 만드는 이유 •‘... it can be imported as its own top-level module, rather than a submodule of mysite.’ •https://docs.djangoproject.com/en/1.4/intro/ tutorial01/#creating-models
  • 42. •mysite/settings.py INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # ... 'webtoon', )
  • 43. •mysite/settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3' 'NAME': 'mysite.db', 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', } }
  • 44. Step 5. 모델 •User •Comic •Episode •Author •Comment
  • 45. •webtoon/models.py from django.db import models class Author(models.Model): name = models.CharField(max_length=200) desc = models.TextField() •https://docs.djangoproject.com/en/dev/ref/models/fields
  • 46. (webtoon)$ python manage.py syncdb Creating tables ... Creating table auth_permission Creating table auth_group_permissions Creating table auth_group Creating table auth_user_user_permissions Creating table auth_user_groups Creating table auth_user Creating table django_content_type Creating table django_session Creating table django_site Creating table webtoon_author You just installed Django's auth system, which means you don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (leave blank to use 'lqez'): lqez E-mail address: ez@smartstudy.co.kr Password: Password (again): Superuser created successfully. Installing custom SQL ... Installing indexes ... Installed 0 object(s) from 0 fixture(s) (webtoon)$
  • 47. •OS X / Linux 에서 LANG 관련 오류가 발생한다면, •LANG 환경 변수가 잘못 정의되어 있거나 비어있어서 발생. •https://code.djangoproject.com/ticket/5846 •아래와 같이 임시로 환경 변수를 설정하여 문제 회피 가능. $ export LANG=en_US.UTF-8 $ export LC_CTYPE=en_US.UTF-8
  • 48. (webtoon)$ python manage.py shell Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) (InteractiveConsole) >>> from webtoon.models import * >>> >>> new_author = Author() >>> new_author.name = "주호민" >>> new_author.desc = "파주스님" >>> new_author.save() >>> >>> authors = Author.objects.all() >>> authors [<Author: Author object>] >>>
  • 49. •webtoon/models.py class Author(models.Model): name = models.CharField(max_length=200) desc = models.TextField() def __unicode__(self): return self.name (webtoon)$ python manage.py shell >>> from webtoon.models import * >>> authors = Author.objects.all() >>> authors [<Author: 주호민>] >>>
  • 50. •webtoon/models.py class Author(models.Model): name = models.CharField(max_length=200) desc = models.TextField() def __unicode__(self): return self.name (webtoon)$ python manage.py shell >>> from webtoon.models import * >>> authors = Author.objects.all() >>> authors [<Author: 주호민>] >>>
  • 51. •Django 의 ORM 기능에 대한 소개는, •https://docs.djangoproject.com/en/1.4/ref/models/querysets/ •https://docs.djangoproject.com/en/1.4/topics/db/queries/
  • 52. Step 6. 관리 페이지 •admin 모듈 추가. •내가 만든 모델을 admin에 노출하기. •ModelAdmin 상속 받아 확장하기. •MEDIA / STATIC 파일 이해.
  • 53. •mysite/settings.py INSTALLED_APPS = ( # ... # Uncomment the next line to enable the admin: 'django.contrib.admin', 'webtoon', ) •mysite/urls.py from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # ... # Uncomment the next line to enable the admin: url(r'^admin/', include(admin.site.urls)), )
  • 54. •관리자 페이지 이용을 위한 로그 테이블 생성 (webtoon)$ python manage.py syncdb Creating tables ... Creating table django_admin_log Installing custom SQL ... Installing indexes ... Installed 0 object(s) from 0 fixture(s) (webtoon)$
  • 56. •webtoon/admin.py (파일이 없으니 생성해주세요) •대부분의 경우 runserver 에서 자동으로 다시 읽어주나, •이 경우는 자동으로 읽어주지 않으니, 종료 후 다시 실행해주세요. from webtoon.models import * from django.contrib import admin admin.site.register(Author)
  • 58.
  • 59. •webtoon/admin.py class AuthorAdmin(admin.ModelAdmin): list_display = ('name', 'desc') admin.site.register(Author, AuthorAdmin)
  • 60.
  • 61. •링크를 통해 완성된 소스를 받아주세요. •webtoon/models.py • https://gist.github.com/3367067 •webtoon/admin.py • https://gist.github.com/3368666 (webtoon)$ python manage.py syncdb Creating tables ... Creating table webtoon_episode Creating table webtoon_comic Creating table webtoon_comment Installing custom SQL ... Installing indexes ... Installed 0 object(s) from 0 fixture(s) (webtoon)$
  • 62. •mysite/settings.py •MEDIA_ROOT : 미디어 파일이 실제 저장될 위치 •MEDIA_URL : 어떤 URL로 미디어 파일을 전달할 것인가 •이미 settings.py 에 변수가 있으니, 찾아서 변경해주세요. import os.path MEDIA_ROOT = os.path.join(os.path.dirname(__file__),"media/") MEDIA_URL = '/media/'
  • 63.
  • 64. •mysite/urls.py import os.path urlpatterns = patterns('', ... (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': os.path.join(os.path.dirname(__file__),'media')} ), ) •STATIC / MEDIA 파일 전달 •원래 Django 의 역할이 아님. •개발 편의를 위해 django.views.static.serve 사용 •Production 에서는 절대 사용 금지!
  • 65.
  • 66. •샘플 데이터베이스 및 파일 다운로드 •데이터베이스 • http://dl.dropbox.com/u/16168259/mysite.db • manage.py 가 있는 위치에 있는 mysite.db 에 덮어 씌우세요. • 관리자 ID : test / PW : test •이미지 파일 • http://dl.dropbox.com/u/16168259/comics.zip • 압축 해제 후, mysite/media/comics 안에 모든 jpg 파일을 복사해주세요. • 모든 이미지는 네이버와 각 작가분에게 저작권이 있습니다. (?)
  • 67. Step 7. 뷰와 템플릿 •뷰 준비하기 •템플릿 만들어보기 •상속된 템플릿 •템플릿 필터 •컨텍스트 프로세서
  • 68. •아래와 같은 URL로 웹 서비스를 하려고 합니다. •웹툰 홈페이지 • /webtoon •작가 페이지 • /webtoon/author/작가 •만화 페이지 • /webtoon/만화 •에피소드 페이지 • /webtoon/만화/에피소드
  • 69. •mysite/urls.py url(r'^webtoon/$', 'webtoon.views.home', name='webtoon'), url(r'^webtoon/author/(?P<author_id>d+)/$', 'webtoon.views.author', name='author'), url(r'^webtoon/(?P<comic_id>d+)/$', 'webtoon.views.comic', name='comic'), url(r'^webtoon/(?P<comic_id>d+)/(?P<episode_id>d+)/$', 'webtoon.views.episode', name='episode'), url(r'^webtoon/$', 'webtoon.views.home', name='webtoon'), url(r'^webtoon/author/(d+)/$', •Named parameter 'webtoon.views.author', name='author'), url(r'^webtoon/(d+)/$', 'webtoon.views.comic', name='comic'), •처음엔 좀 복잡해 보이지만, url(r'^webtoon/(d+)/(d+)/$', 'webtoon.views.episode', name='episode'), •의미 전달에 용이
  • 70. •webtoon/views.py from django.http import HttpResponse def home(request): return HttpResponse('Home of webtoon service') def author(request, author_id): return HttpResponse('Author %s page' % author_id) def comic(request, comic_id): return HttpResponse('Comic %s page' % comic_id) def episode(request, comic_id, episode_id): return HttpResponse('Episode %s of Comic %s page' % (episode_id, comic_id) )
  • 71. •웹툰 홈페이지 http://localhost:8000/webtoon •작가 페이지 http://localhost:8000/webtoon/author/1 •만화 페이지 http://localhost:8000/webtoon/1 •에피소드 페이지 http://localhost:8000/webtoon/1/1 •URL 마지막에 자동으로 / 붙음. settings.APPEND_SLASH = True • HTTP 301 로 Redirection 시키므로, 원하지 않는 경우 url을 잘 설정 하고 해당 기능을 꺼야 함.
  • 72. •webtoon/views.py from django.template.context import RequestContext from django.template.loader import get_template def home(request): template = get_template('home.html') variables = RequestContext(request, {}) output = template.render(variables) return HttpResponse(output) (...)
  • 73. •webtoon/templates/home.html • 공용 템플릿은 프로젝트 디렉토리의 templates 에, • 앱의 템플릿은 앱 디렉토리의 templates 에 놔두면 좋습니다. <html> <head> <meta charset="utf-8" /> <title>Django 웹툰</title> </head> <body> <h1>Django 웹툰</h1> <p>Django 웹툰에 오신 것을 환영합니다.</p> </body> </html>
  • 74.
  • 75. •webtoon/templates/home.html <html> <head> <title>Django 웹툰</title> </head> <body> <h1>Django 웹툰</h1> <p>Django 웹툰에 오신 것을 환영합니다.</p> <ul> {% for episode in episodes %} <li>{{ episode.title }}</li> {% endfor %} </ul> </body> </html>
  • 76. •webtoon/views.py from webtoon.models import * def home(request): template = get_template('home.html') episodes = Episode.objects.all() variables = RequestContext(request, { 'episodes': episodes, }) output = template.render(variables) return HttpResponse(output)
  • 77.
  • 78. •webtoon/templates/home.html (...) <li> <a href="{% url episode episode.comic.id episode.id %}"> {{ episode.title }} </a> </li> (...)
  • 79.
  • 80. •webtoon/templates/episode.html <html> <head> <title>{{ episode.title }} :: {{ episode.comic.title }} :: Django 웹툰</title> </head> <body> <h1><a href="{% url webtoon %}">Django 웹툰</a></h1> <h2><a href="{% url comic episode.comic.id %}">{{ episode.comic.title }}</a></h2> <h3>{{ episode.title }}</h3> <img src="{{ episode.img_file.url }}"> </body> </html>
  • 81. •webtoon/views.py def episode(request, comic_id, episode_id): template = get_template('episode.html') episode = Episode.objects.get(id=episode_id) variables = RequestContext(request, { 'episode': episode, }) output = template.render(variables) return HttpResponse(output)
  • 82.
  • 83. •공통된 부분을 부모 템플릿으로 생성 • 상속 : {% extends “base.html” %} • 포함 : {% include “part.html” %} • 대체 : {% block foo %} {% endblock %} • {{ block.super }} 로 부모의 내용을 포함 가능 •webtoon/templates/base.html <html> <head> <title>{% block title %}Django 웹툰{% endblock %}</title> {% block head %}{% endblock %} </head> <body> {% block content %}{% endblock %} </body> </html>
  • 84. •webtoon/templates/episode.html {% extends "base.html" %} {% block title %} {{ episode.title }} :: {{ episode.comic.title }} :: Django 웹툰 {% endblock %} {% block content %} <h1><a href="{% url webtoon %}">Django 웹툰</a></h1> <h2><a href="{% url comic episode.comic.id %}">{{ episode.comic.title }}</a></h2> <h3>{{ episode.title }}</h3> <img src="{{ episode.img_file.url }}"> {% endblock %}
  • 85. •webtoon/templates/copyright.html <div>모든 만화의 저작권은 각 작가에게 있습니다.</div> •webtoon/templates/base.html <html> <head> <title>{% block title %}Django 웹툰{% endblock %}</title> {% block head %}{% endblock %} </head> <body> {% block content %}{% endblock %} {% include "copyright.html" %} </body> </html>
  • 86. •더 해보기 •/webtoon/author 뷰 구현 • 작가 소개 • 작가가 그린 만화 링크 •/webtoon/comic 뷰 구현 • 해당 만화 작가 페이지로의 링크 • 해당 만화에 속해있는 에피소드 출력하기 •/webtoon개선 • 최근 만화 n개만 출력 • 작가별 링크
  • 87. Step 9. 사용자 입력 •로그인 / 로그아웃 •폼 처리 •댓글 달기
  • 88. •mysite/urls.py •기본 로그인 모듈의 경로를 모두 추가 •로그인 : /accounts/login •로그아웃 : /accounts/logout (r'^accounts/', include('django.contrib.auth.urls')),
  • 90. •mysite/settings.py •공용 템플릿들을 보관하기 위해 디렉토리 경로 추가 TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__),"templates"), ) •mysite/templates/registration/login.html {% extends "base.html" %} {% block content %} <form method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="로그인" /> </form> {% endblock %}
  • 91.
  • 92. •왜 로그인 이후에 /accounts/profile 로 가는가?
  • 93. •mysite/settings.py •LOGIN_URL : 로그인 페이지 •LOGIN_REDIRECT_URL : 로그인 이후 갈 페이지 •https://docs.djangoproject.com/en/1.4/topics/auth/ LOGIN_URL = '/accounts/login/' LOGIN_REDIRECT_URL = '/webtoon/'
  • 94. •로그인 여부 확인 •in Python : if request.user.is_authenticated(): •in Template : {% if user.is_authenticated %}
  • 95. •webtoon/templates/comment.html {% if user.is_authenticated %} <p>{{ user.username }} 사용자로 이름으로 댓글 달기</p> <form method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="댓글" /> </form> {% else %} <p> <a href="{% url login %}"> 댓글을 달려면 로그인 해주세요. </a> </p> {% endif %}
  • 96. •webtoon/templates/episode.html {% block content %} (...) <img src="{{ episode.img_file.url }}"> {% include "comment.html" %} {% endblock %} •webtoon/forms.py •https://docs.djangoproject.com/en/1.4/topics/forms/ from django import forms class CommentForm(forms.Form): msg = forms.CharField(max_length=200)
  • 97. •webtoon/views.py from django.http import HttpResponseRedirect from datetime import datetime from webtoon.forms import * (...) def episode(request, comic_id, episode_id): template = get_template('episode.html') episode = Episode.objects.get(id=episode_id) if request.method == 'POST': form = CommentForm(request.POST) if form.is_valid(): comment = Comment() comment.msg = form.cleaned_data['msg'] comment.user = request.user comment.episode = episode comment.written_date = datetime.now() comment.save() return HttpResponseRedirect(request.get_full_path()) else: form = CommentForm()
  • 98. •webtoon/views.py (이전 페이지에 이어서) (...) variables = RequestContext(request, { 'episode': episode, 'form': form, }) output = template.render(variables) return HttpResponse(output)
  • 99. •webtoon/views.py (...) def episode(request, comic_id, episode_id): # ... comments = Comment.objects.filter(episode=episode_id) variables = RequestContext(request, { 'episode': episode, 'form': form, 'comments': comments, })
  • 100. •webtoon/templates/comment.html (...) {% if comments %} 댓글( 총 {{ comments|length }} 개 ) <ul> {% for c in comments %} <li>{{ c.user.username }} : {{ c.msg }} / {{ c.written_date }}</li> {% endfor %} </ul> {% endif %} •length 등, 변수에 | (pipe)로 연결되는 것은 ‘템플릿 필터’ •템플릿에서 간단한 처리가 가능한 것들은 필터로 처리 •https://docs.djangoproject.com/en/1.4/ref/templates/builtins/
  • 101. •로그인하고 나서 다시 원래 자리로 돌아오려면? •next 인자로 URL 전달 - 근데 템플릿에서 현재 URL을 모른다? •TEMPLATE_CONTEXT_PROCESSOR •모든 템플릿에 전달되는 기본 값들의 집합 •필요한 경우 컨텍스트 프로세서를 추가해서 사용하면 됨. •mysite/settings.py from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP TEMPLATE_CONTEXT_PROCESSORS = TCP + ( 'django.core.context_processors.request', )
  • 102. •webtoon/templates/comment.html {% if user.is_authenticated %} (...) {% else %} <p> <a href="{% url login %}?next={{ request.get_full_path }}"> 댓글을 달려면 로그인 해주세요. </a> </p> {% endif %} (...)
  • 103. •어? 가입 페이지가 없잖아?! 일단 shell로 추가해보자. (webtoon)$ python manage.py shell Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) (InteractiveConsole) >>> from django.contrib.auth.models import User >>> user = User.objects.create_user( ... username='anonymous', ... email='foo@bar.com', ... password='1234') >>> user.save() >>>
  • 104. •더 해보기 •폼을 이용한 가입 페이지 만들기 • from django.contrib.auth.forms import UserCreationForm • http://www.djangobook.com/en/2.0/chapter14/ •댓글 달기를 POST 대신 AJAX로 처리해보기 •댓글이 많은 경우 어떻게 할 것인가? • /webtoon/comic_id/episode_id/comments
  • 105. Step 10. 마무리 •css 적용 •admin 페이지에 검색 기능, 리스트 필터 등 넣어보기 •django-debug-toolbar
  • 106. •webtoon/static/css/webtoon.css •* { font-family: sans-serif; } •webtoon/static/img/django.gif •http://dl.dropbox.com/u/16168259/django.gif •webtoon/templates/base.html html> <head> <meta charset="utf-8" /> <title>{% block title %}Django 웹툰{% endblock %}</title> <link rel="stylesheet" href="{{ STATIC_URL }}css/webtoon.css"> {% block head %}{% endblock %} </head> <body> {% block content %}{% endblock %} {% include "copyright.html" %} <img src="{{ STATIC_URL }}img/django.gif"> </body> </html>
  • 107. •STATIC_ROOT / STATIC_URL •템플릿과 마찬가지로 앱 별 STATIC 파일과, •전역으로 사용할 STATIC 파일은 별도로 관리. STATICFILES_DIRS = ( os.path.join(os.path.dirname(__file__),"static"), ) •어? MEDIA 와는 다르게 왜 되는거지? •STATIC_URL 이 지정되어 있고, •settings.STATICFILES_FINDERS 에 AppDirectoriesFinder 가 등록되어 있음. •MEDIA와 마찬가지로, Production에서는 사용하지 마세요.
  • 108. •관리 페이지 기능 개선 •search_fields : 검색 대상 •ordering : 기본 정렬 •https://docs.djangoproject.com/en/1.4/ref/contrib/admin/ •webtoon/admin.py class EpisodeAdmin(admin.ModelAdmin): list_display = ('comic', 'title', 'pub_date') search_fields = ['title','comic__title'] ordering = ['-pub_date'] admin.site.register(Episode, EpisodeAdmin)
  • 109. •Django debug toolbar •http://blog.naver.com/ez_/140162876100 (webtoon)$ pip install django-debug-toolbar MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',) INSTALLED_APPS += ('debug_toolbar',) INTERNAL_IPS = ('127.0.0.1',) DEBUG_TOOLBAR_PANELS = ( 'debug_toolbar.panels.version.VersionDebugPanel', 'debug_toolbar.panels.timer.TimerDebugPanel', 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel', 'debug_toolbar.panels.headers.HeaderDebugPanel', 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel', 'debug_toolbar.panels.template.TemplateDebugPanel', 'debug_toolbar.panels.sql.SQLDebugPanel', 'debug_toolbar.panels.signals.SignalDebugPanel', 'debug_toolbar.panels.logger.LoggingPanel', 'debug_toolbar.panels.profiling.ProfilingDebugPanel', )
  • 110.
  • 111. 집에서 더 해볼만한 것 •South 를 통해 기존 모델 변경해보기 •http://jcstyle.tistory.com/entry/django-migration-tool- South-%EC%9E%91%EC%97%85%EA%B8%B0 •별점 주기 기능 추가 •Rating Model 을 추가하는 것으로 시작.
  • 112. 참여한 분들에게 바라는 점 •오늘 실습을 끝까지 진행하지 못했어도, •환경은 구축되었으므로, 나머지를 끝까지 진행해주세요. •주변에 많이 소개해주세요. •스마트스터디는 이상한 회사다! •블로그 등으로 써주시고, 저희 페이스북 페이지에 알려주세요 :D