Differences between revisions 3 and 31 (spanning 28 versions)
Revision 3 as of 2006-09-21 16:31:55
Size: 672
Editor: 211
Comment:
Revision 31 as of 2013-06-17 15:13:10
Size: 8485
Editor: 61
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
#acl falsetru:read,write,revert,delete

[Django] 발표자료 준비 in Framework2.1(세미나 준비를 위한 임시공간)
 1. [http://bbs.python.or.kr/viewtopic.php?t=22325 파이썬마을]
 1.
[http://forum.rubykr.org/ 루비사용자모임]
 1. [wiki:
Blog/251 yong27 블로그]

프레젠테이션 파일 : attachment:Django.ppt (잦은 갱신 요망)
[[Django]] 발표자료 준비 in Framework2.1(세미나 준비를 위한 임시공간)
 * AltLang:Framework2.1
 * [
[http://bbs.python.or.kr/viewtopic.php?t=22325|파이썬마을]]
 * [
[http://forum.rubykr.org/|루비사용자모임]]
 * [[
Blog:251|yong27 블로그]]

<<TableOfContents>>

== 발표자료준비 ==

프레젠테이션 파일 : [[attachment:Django.ppt]]
Line 15: Line 17:
논의
 * 토론시간에 토론할 주제에 대해서 황대산씨(MSN: daesan@gmail.com)와 의논.
== 설명시 사용할 예제 모델 ==
간단한 블로그
{{{#!python
from django.db import models

class Post(models.Model):
    title = models.CharField(maxlength=200)
    content = models.TextField(maxlength=2000)
    ctime = models.DateTimeField(auto_now_add=True)
    mtime = models.DateTimeField(auto_now=True)
    is_public = models.BooleanField()
    tags = models.ManyToManyField('Tag')

class Comment(models.Model):
    post = models.ForeignKey(Post)
    who = models.CharField(maxlength=30)
    content = models.TextField(maxlength=1000)

class Tag(models.Model):
    name = models.CharField(maxlength=30)
}}}

== 관리자 인터페이스 간단 시연 ==
위 모델을 admin 으로 데이터 입출력, 및 디스플레이 방법 시연

== 토론 준비 ==
=== 토론 주제들 ===
지난 모임에서 거론된 토론주제
 * ORM
 * 테이블 관계 설정
 * 데이타 검증
 * 관리자 인터페이스
 * 뷰, 템플릿
 * URL 구조

그밖에 황대산님과의 이야기를 통해
 * [AJAX] 구현예제
 * 일반적인 개발 프로세스
 * DB 특정 기능들 (self join, 정의되지 않은 객체이름 사용, custom SQL, legacy DB쓰기)
 * url 임의 매핑
 * 템플릿에 변수넘기기
 * 테스팅 프레임워크
 * 변경된 DB의 migration
 * 로그인, 사용자, 그룹관리

=== 데이터 검증 관련 코드 ===
!AddManipulator, !ChangeManipulator가 있다. 데이터 입력부분 view는 다음처럼,

{{{#!python
def create_post(request):
    manipulator = Post.AddManipulator()
    if request.POST:
        new_data = request.POST.copy()
        errors = manipulator.get_validation_errors(new_data)
        if not errors:
            manipulator.do_html2python(new_data)
            new_post = manipulator.save(new_data)
            return HttpResponseRedirect("/blog/%i/" % new_post.id)
    else:
        errors = new_data = {}

    form = forms.FormWrapper(manipulator, new_data, errors)
    return render_to_response('blog/create_form.html', {'form': form})
}}}

여기서 create_form.html 은 다음처럼
{{{

<h1>Create a post:</h1>

{% if form.has_errors %}
<h2>Please correct the following error{{ form.error_dict|pluralize }}:</h2>
{% endif %}

<form method="post" action=".">
<p>
    <label for="id_title">Title:</label> {{ form.title }}
    {% if form.title.errors %}*** {{ form.title.errors|join:", " }}{% endif %}
</p>
<p>
    <label for="id_content">Content:</label> {{ form.content }}
    {% if form.content.errors %}*** {{ form.content.errors|join:", " }}{% endif %}
</p>
<p>
    <label for="id_is_public">Is public?:</label> {{ form.is_public }}
    {% if form.is_public.errors %}*** {{ form.is_public.errors|join:", " }}{% endif %}
</p>
<input type="submit" />
</form>
}}}

=== AJAX 구현예제 ===
따로 JavaScript 를 제공하지 않는다. 직접 구현하거나, [Prototype] 등의 라이브러리 따로 추가하여 사용 가능

{{{
<script src="js/prototype.js" type="text/javascript"></script>
<script type="text/javascript">
function check() {
    new Ajax.Updater('result', '/rpc/', {
            method: 'get',
            parameters: 'id=' + id
    });
}
</script>

<form onsubmit="check(); return false;">
...
</form>
<div id="result">
</div>
}}}

=== 일반적인 개발 프로세스 ===

{{{#!dot
digraph G {
    rankdir=LR;
    startproject -> startapp -> model -> syncdb -> admin -> url -> view -> template
    template -> view
    template -> model
}
}}}

=== 데이터베이스 관련 특정 기능들 ===
Recursive relationship
{{{#!python
class Person:
    name = Model.CharField(maxlength=30)
    father = Model.ForeighKey('self')
    mother = Model.ForeighKey('self')
}}}

Custom SQL
{{{#!python
def my_custom_sql(self):
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    row = cursor.fetchone()
    return row
}}}

Integrating with a legacy database
{{{
django-admin.py inspectdb --settings=path.to.settings > models.py
}}}

=== 로그인 ===
urls.py에 다음만 추가하면 가능
{{{#!python
urlpatterns = patterns('',
     (r'^login/', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),
     (r'^logout/', 'django.contrib.auth.views.logout', {'next_page': '/asdf/'}),
)
}}}

=== Testing framework ===
테스팅 방법
 * application root에 tests.py UnitTest 파일 생성
 * 수행은 '''manage.py test'''
 * 매 테스트마다, 임시 데이터베이스 생성 후, 테스트 수행

Unit Test
{{{#!python
import unittest
from myapp.models import Animal

class AnimalTestCase(unittest.TestCase):

    def setUp(self):
        self.lion = Animal.objects.create(name="lion", sound="roar")
        self.cat = Animal.objects.create(name="cat", sound="meow")

    def testSpeaking(self):
        self.assertEquals(self.lion.speak(), 'The lion says "roar"')
        self.assertEquals(self.cat.speak(), 'The cat says "meow"')
}}}

Function Test
{{{#!python
import unittest
from django.test.client import Client

class SimpleTest(unittest.TestCase):
    def setUp(self):
        # Every test needs a client
        self.client = Client()
    def test_details(self):
        # Issue a GET request
        response = self.client.get('/customer/details/')

        # Check that the respose is 200 OK
        self.failUnlessEqual(response.status_code, 200)
        # Check that the rendered context contains 5 customers
        self.failUnlessEqual(len(response.context['customers']), 5)
}}}

{{{
Testing Responses
~~~~~~~~~~~~~~~~~

The ``get()``, ``post()`` and ``login()`` methods all return a Response
object. This Response object has the following properties that can be used
for testing purposes:

    =============== ==========================================================
    Property Description
    =============== ==========================================================
    ``status_code`` The HTTP status of the response. See RFC2616_ for a
                     full list of HTTP status codes.

    ``content`` The body of the response. The is the final page
                     content as rendered by the view, or any error message
                     (such as the URL for a 302 redirect).

    ``template`` The Template instance that was used to render the final
                     content. Testing ``template.name`` can be particularly
                     useful; if the template was loaded from a file,
                     ``template.name`` will be the file name that was loaded.

                     If multiple templates were rendered, (e.g., if one
                     template includes another template),``template`` will
                     be a list of Template objects, in the order in which
                     they were rendered.

    ``context`` The Context that was used to render the template that
                     produced the response content.

                     As with ``template``, if multiple templates were rendered
                     ``context`` will be a list of Context objects, stored in
                     the order in which they were rendered.
    =============== ==========================================================
}}}


== migration (sqlite3) ==
 1. dump
  sqlite3 f.db ".dump blog_post" > blog_post.sql
 1. drop table
  sqlite3 f.db "drop table blog_post"
 1. ./manage.py syncdb
 1. blog_post.sql 를 가내수공업으로 조작
 1. sqlite3 f.db ".read blog_post.sql"

== 끝나고 ==
 1. [[http://altlang.org/fest/Framework2.1/%ED%9B%84%EA%B8%B0|회고들]]
 1. [[http://video.google.com/videoplay?docid=1703050267614397553&q=FW21|동영상]]

Django 발표자료 준비 in Framework2.1(세미나 준비를 위한 임시공간)

발표자료준비

프레젠테이션 파일 : Django.ppt

관련자료들

설명시 사용할 예제 모델

간단한 블로그

   1 from django.db import models
   2 
   3 class Post(models.Model):
   4     title = models.CharField(maxlength=200)
   5     content = models.TextField(maxlength=2000)
   6     ctime = models.DateTimeField(auto_now_add=True)
   7     mtime = models.DateTimeField(auto_now=True)
   8     is_public = models.BooleanField()
   9     tags = models.ManyToManyField('Tag')
  10 
  11 class Comment(models.Model):
  12     post = models.ForeignKey(Post)
  13     who = models.CharField(maxlength=30)
  14     content = models.TextField(maxlength=1000)
  15 
  16 class Tag(models.Model):
  17     name = models.CharField(maxlength=30)

관리자 인터페이스 간단 시연

위 모델을 admin 으로 데이터 입출력, 및 디스플레이 방법 시연

토론 준비

토론 주제들

지난 모임에서 거론된 토론주제

  • ORM
  • 테이블 관계 설정
  • 데이타 검증
  • 관리자 인터페이스
  • 뷰, 템플릿
  • URL 구조

그밖에 황대산님과의 이야기를 통해

  • [AJAX] 구현예제
  • 일반적인 개발 프로세스
  • DB 특정 기능들 (self join, 정의되지 않은 객체이름 사용, custom SQL, legacy DB쓰기)
  • url 임의 매핑
  • 템플릿에 변수넘기기
  • 테스팅 프레임워크
  • 변경된 DB의 migration
  • 로그인, 사용자, 그룹관리

데이터 검증 관련 코드

AddManipulator, ChangeManipulator가 있다. 데이터 입력부분 view는 다음처럼,

   1 def create_post(request):
   2     manipulator = Post.AddManipulator()
   3     if request.POST:
   4         new_data = request.POST.copy()
   5         errors = manipulator.get_validation_errors(new_data)
   6         if not errors:
   7             manipulator.do_html2python(new_data)
   8             new_post = manipulator.save(new_data)
   9             return HttpResponseRedirect("/blog/%i/" % new_post.id)
  10     else:
  11         errors = new_data = {}
  12 
  13     form = forms.FormWrapper(manipulator, new_data, errors)
  14     return render_to_response('blog/create_form.html', {'form': form})

여기서 create_form.html 은 다음처럼

<h1>Create a post:</h1>

{% if form.has_errors %}
<h2>Please correct the following error{{ form.error_dict|pluralize }}:</h2>
{% endif %}

<form method="post" action=".">
<p>
    <label for="id_title">Title:</label> {{ form.title }}
    {% if form.title.errors %}*** {{ form.title.errors|join:", " }}{% endif %}
</p>
<p>
    <label for="id_content">Content:</label> {{ form.content }}
    {% if form.content.errors %}*** {{ form.content.errors|join:", " }}{% endif %}
</p>
<p>
    <label for="id_is_public">Is public?:</label> {{ form.is_public }}
    {% if form.is_public.errors %}*** {{ form.is_public.errors|join:", " }}{% endif %}
</p>
<input type="submit" />
</form>

AJAX 구현예제

따로 JavaScript 를 제공하지 않는다. 직접 구현하거나, [Prototype] 등의 라이브러리 따로 추가하여 사용 가능

<script src="js/prototype.js" type="text/javascript"></script>
<script type="text/javascript">
function check() {
    new Ajax.Updater('result', '/rpc/', {
            method: 'get',
            parameters: 'id=' + id
    });
}
</script>

<form onsubmit="check(); return false;">
...
</form>
<div id="result">
</div>

일반적인 개발 프로세스

데이터베이스 관련 특정 기능들

Recursive relationship

   1 class Person:
   2     name = Model.CharField(maxlength=30)
   3     father = Model.ForeighKey('self')
   4     mother = Model.ForeighKey('self')

Custom SQL

   1 def my_custom_sql(self):
   2     from django.db import connection
   3     cursor = connection.cursor()
   4     cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
   5     row = cursor.fetchone()
   6     return row

Integrating with a legacy database

django-admin.py inspectdb --settings=path.to.settings > models.py

로그인

urls.py에 다음만 추가하면 가능

   1 urlpatterns = patterns('',
   2      (r'^login/', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),
   3      (r'^logout/', 'django.contrib.auth.views.logout', {'next_page': '/asdf/'}),
   4 )

Testing framework

테스팅 방법

  • application root에 tests.py UnitTest 파일 생성

  • 수행은 manage.py test

  • 매 테스트마다, 임시 데이터베이스 생성 후, 테스트 수행

Unit Test

   1 import unittest
   2 from myapp.models import Animal
   3 
   4 class AnimalTestCase(unittest.TestCase):
   5 
   6     def setUp(self):
   7         self.lion = Animal.objects.create(name="lion", sound="roar")
   8         self.cat = Animal.objects.create(name="cat", sound="meow")
   9 
  10     def testSpeaking(self):
  11         self.assertEquals(self.lion.speak(), 'The lion says "roar"')
  12         self.assertEquals(self.cat.speak(), 'The cat says "meow"')

Function Test

   1 import unittest
   2 from django.test.client import Client
   3 
   4 class SimpleTest(unittest.TestCase):
   5     def setUp(self):
   6         # Every test needs a client
   7         self.client = Client()
   8     def test_details(self):
   9         # Issue a GET request
  10         response = self.client.get('/customer/details/')
  11 
  12         # Check that the respose is 200 OK
  13         self.failUnlessEqual(response.status_code, 200)
  14         # Check that the rendered context contains 5 customers
  15         self.failUnlessEqual(len(response.context['customers']), 5)

Testing Responses
~~~~~~~~~~~~~~~~~

The ``get()``, ``post()`` and ``login()`` methods all return a Response
object. This Response object has the following properties that can be used
for testing purposes:

    ===============  ==========================================================
    Property         Description
    ===============  ==========================================================
    ``status_code``  The HTTP status of the response. See RFC2616_ for a
                     full list of HTTP status codes.

    ``content``      The body of the response. The is the final page
                     content as rendered by the view, or any error message
                     (such as the URL for a 302 redirect).

    ``template``     The Template instance that was used to render the final
                     content. Testing ``template.name`` can be particularly
                     useful; if the template was loaded from a file,
                     ``template.name`` will be the file name that was loaded.

                     If multiple templates were rendered, (e.g., if one
                     template includes another template),``template`` will
                     be a list of Template objects, in the order in which
                     they were rendered.

    ``context``      The Context that was used to render the template that
                     produced the response content.

                     As with ``template``, if multiple templates were rendered
                     ``context`` will be a list of Context objects, stored in
                     the order in which they were rendered.
    ===============  ==========================================================

migration (sqlite3)

  1. dump
    • sqlite3 f.db ".dump blog_post" > blog_post.sql

  2. drop table
    • sqlite3 f.db "drop table blog_post"
  3. ./manage.py syncdb
  4. blog_post.sql 를 가내수공업으로 조작
  5. sqlite3 f.db ".read blog_post.sql"

끝나고

  1. 회고들

  2. 동영상

DjangoOnFramework2.1 (last edited 2013-06-17 15:13:10 by 61)

web biohackers.net