블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

파이썬 전역 변수

프로그래밍/Python | 2017.04.11 00:05 | Posted by 조대협

파이썬에서 전역변수 사용하기 (2.7X 버전)


조대협 (http://bcho.tistory.com)


파이썬에서 전역 변수를 사용하려고 하니 "Unbound Local Error"가 나더라.

파이썬은 로컬 변수를 자바처럼 쓸수가 없다.


잘못된 코드


global_value = 1


def myfunction():

  global_value=global_value + 1


올바른 코드


global_value = 1


def myfunction():

  global global_value

  global_value=global_value + 1


글로벌 변수로 쓰려면, 글로벌 변수를 쓰려는 곳에서 global 이라는 키워드로 선언을 해줘야 그 전역 변수를 불러다가 쓸 수 있다.



저작자 표시 비영리
신고

django 에서 REST API 만들기

프로그래밍/Python | 2014.01.08 00:58 | Posted by 조대협

Dango에서 간단한 REST API 만들기 

조대협



Django에서 REST API를 만들려면 가장 널리 사용되는 프레임웍중 하나가 dango rest_framework이다.

http://django-rest-framework.org/tutorial/quickstart


설치는 다음과 같다.

pip install djangorestframework

pip install markdown       # Markdown support for the browsable API.

pip install django-filter  # Filtering support

 

1. quickstart라는 앱을 생성

 

C:\Users\terry\git\django_restframework_sample\django_restframework_sample>python manage.py startapp quickstart

또는 이클립스 사용시에는 project에서 오른쪽 버튼 누르고 django 메뉴에서 > Custom command (manage.py xxx)에서 startapp 명령어 실행

 



아래와 같이 프로젝트 아래에 앱이 생성된



 

2. DB sync

setting.py에 아래 내용을 추가

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.sqlite3',

        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

        'USER': '',

        'PASSWORD': '',

        'HOST': '',

        'PORT': ''

    }

}

다음 eclipse에서 마찬가지로 오른쪽 버튼을 눌러서, django 메뉴에서 manage.py syncdb 명령어를 수행



이 예제에서는 실제 테이블은 만들지 않고, API 인증을 위해서, django user 테이블만을 생성한다. Syncdb를 수행하면 아래와 같이 첫 user를 만드는데, 이때, 사용자 id,email,password를 입력하도록 한다.



 

3. 다음으로 코딩

1) quickstart/serializer.py 코드를 아래와 같이 작성

from django.contrib.auth.models import User, Group

from rest_framework import serializers

 

 

class UserSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:

        model = User

        fields = ('url', 'username', 'email', 'groups')

 

 

class GroupSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:

        model = Group

        fields = ('url', 'name')

 

2) quickstart/views.py를 다음과 같이 작성

from django.contrib.auth.models import User, Group

from rest_framework import viewsets

from quickstart.serializers import UserSerializer, GroupSerializer

 

 

class UserViewSet(viewsets.ModelViewSet):

    """

    API endpoint that allows users to be viewed or edited.

    """

    queryset = User.objects.all()

    serializer_class = UserSerializer

 

 

class GroupViewSet(viewsets.ModelViewSet):

    """

    API endpoint that allows groups to be viewed or edited.

    """

    queryset = Group.objects.all()

    serializer_class = GroupSerializer

 

위의 테스트 앱은 UserViewSet은 현재 Django에 등록된 사용자 리스트들을 읽어다가 JSON으로 리턴하는 클래스 이고, GroupViewSet은 마찬가지로 django에 등록된 사용자 그룹 리스트를 읽어다가 JSON으로 리턴하는 클래스이다.

 

Rather than write multiple views we're grouping together all the common behavior into classes called ViewSets.

We can easily break these down into individual views if we need to, but using viewsets keeps the view logic nicely organized as well as being very concise.

Notice that our viewset classes here are a little different from those in the frontpage example, as they include queryset andserializer_class attributes, instead of a model attribute.

For trivial cases you can simply set a model attribute on the ViewSet class and the serializer and queryset will be automatically generated for you. Setting the queryset and/or serializer_class attributes gives you more explicit control of the API behaviour, and is the recommended style for most applications.

4. 다음으로 세팅

1) root project(여기서는 django_restframework_sample) urls.py에 다음 코드를 추가함

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

from rest_framework import routers

from quickstart import views

 

router = routers.DefaultRouter()

router.register(r'users', views.UserViewSet)

router.register(r'groups', views.GroupViewSet)

 

# Wire up our API using automatic URL routing.

# Additionally, we include login URLs for the browseable API.

urlpatterns = patterns('',

    url(r'^', include(router.urls)),

    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))

)

일반적인 web application과 다르게 view가 아닌 viewset을 사용하기 때문에, URL rest_framework이 자동으로 설정하도록 세팅하였다.

l  /users à views.UserViewSet API로 맵핑 되고

l  /groups à views.GroupViewSet API로 맵핑 된다.

 

2) Root project setting.py에 다음을 추가

REST_FRAMEWORK = {

    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),

    'PAGINATE_BY': 10

}

이 부분이 흥미로운 부분인데, JSON 기반의 API 인증(Authentication)  인가(Authorization)을 프레임웍 자체에서 제공한다. 위의 경우에는 Admin 사용자에 대해서만 서비스를 제공하고, HTTP BASIC AUTH 인증을 사용한다.

http://django-rest-framework.org/api-guide/permissions 에 자세한 내용이 나와 았는데,  

  모든 사용자에게 access를 허가하는 Allow Any

  인증된 사용자에게만 access를 허가하는 isAuthenticated

  관리자에게만 인증을 허가하는 isAdminUser

  인증되지 않은 사용자에게는 Read,인증된 사용자에게는 Update를 제공하는 isAuthenticatedOrReadOnly

  기타 DjangoModel (django.contrib.auth에 의해서 관리되는 권한)이나 Object 단위 권한등에 따라서, 조정할 수 있다.

  그리고 TokenHasReadWriteScope의 경우에는 OAuth2Authentication등과 연계하여 Token 기반의 인증이 가능하게 된다.

※ 다양한 인증 메커니즘을 제공하기 때문에, 처음에는 어려울지 몰라도, 이해하고 나면 짜는 것 보다는 훨씬 쉬울듯.

위는 API접근 권한에 대한 것이었고, Authenticationhttp://django-rest-framework.org/api-guide/authentication 에 정의되어 있다. 위에서 사용한 것과 같이 HTTP Basic Auth를 사용할 수 도 있고, Token이나 Http Session 기반의 Authentication 그리고, OAuth 1,2 기반의 인증을 모두 지원한다. (Token 방식의 경우에는 userauthenticated된 다음, Authorization token을 서버에서 발급해준다. Token HTTP를 타고 내려가기 때문에, Token secure하게 전달하기 위해서 HTTPS를 필수로 사용해야 한다.)

 

 

3) 그리고, setting.py INSTALLED_APPS rest_framwwork을 추가하는 것도 있지 말자

INSTALLED_APPS = (

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'rest_framework',

)

5. 테스팅

테스트는 Chrome plug-inadvanced rest client를 사용하였다.

여기서 주목할 것은 HTTP Basic Auth 헤더를 어떻게 입력하느냐인데,

Headers 메뉴에서 Form을 선택한후 Add new header에서 Key Authorization을 선택한다.



Authorization이 선택되면 value를 넣는 부분에 아래와 같이 Construct라는 버튼이 나타나는데,



이 버튼을 누르게 되면 아래와 같이 dialog box가 나와서 basic 며소에 대한 log in id password를 넣을 수 있게 된다.



이 과정이 끝나면 Header 부분에 HTTP Basic Auth 부분이 들어가게 되고, 아래와 같은 테스트 결과를 얻게 된다.

 




대부분의 내용은 http://django-rest-framework.org/tutorial/quickstart 를 참고하였음


저작자 표시
신고

Python 공부 노트 11. Class

프로그래밍/Python | 2014.01.03 00:33 | Posted by 조대협


class 클래스명(ParentClass명):

  def __init__(self,인자....) # 생성자임

    ParentClass명.__init__(self) # 부모 생성자를 불러줌

  

 def mymethod(self): # 모든 메서드에는 "self"를 인자로 받아야함

    self.myname = 'terry'  # 클래스내의 내부 변수는 self로 시작함


 def call(self):

   self.mymethod() # 다른 내부 메서드를 부를때에는 self.method 명으로 불러야함

저작자 표시
신고

Python 공부 노트 11. Module install

프로그래밍/Python | 2014.01.02 20:03 | Posted by 조대협

1. pip 를 이용한 인스톨

- 먼저 pip가 깔려 있어야 한다. $Python_home/scripts에 들어가서 %> easy_install pip 를 하면 pip가 인스톨 됨

- 그후에, pip {모듈명}


2. 방화벽등으로 인하여 easy_install등이 불가할 경우

- 모듈을 다운로드 받고 압축을 푼다. (보통 install을 위한 setup.py 파일이 있음)

- python setup.py install 을 수행

저작자 표시
신고

'프로그래밍 > Python' 카테고리의 다른 글

django 에서 REST API 만들기  (1) 2014.01.08
Python 공부 노트 11. Class  (0) 2014.01.03
Python 공부 노트 11. Module install  (0) 2014.01.02
Python에서 Open API 호출하기  (0) 2013.11.22
Django에서 static file (css,img 사용하기)  (0) 2013.11.21
Django Template  (0) 2013.11.21

Python에서 Open API 호출하기

프로그래밍/Python | 2013.11.22 19:09 | Posted by 조대협

Rest API를 호출하기

여러가지 라이브러리 (urllib2, httplib2)등을 체크해봤으나, https 를 가장 쉽게 호출할 수 있고, 사용하기 편한것은 requests라는 것이 가장 편리함 http://www.python-requests.org/en/latest/user/quickstart/#make-a-request 에서 curl 로 다운로드 하고 설치해서 사용



위는 도스창을 이용해서 간단하게 https로 dna.daum.net을 호출한 코드인데, 리턴값이 한글이라서 그런지. cp949 encode 에러가 남. (이건 나중에 수정해야 할거 같고)


기타 참고 자료 (아래)


참고 : API 호출 하기

https://dna.daum.net/tools/python/tutorial


SSL 사용하기

urllib2는 https가 지원되지 않음


1. Python 인스톨본이 SSL을 지원해야 한다.

. 확인하는법

>>> import socket

>>> socket.ssl

<function ssl at 0x4038b0>


2. httplib2 설치

https://code.google.com/p/httplib2/



저작자 표시
신고

'프로그래밍 > Python' 카테고리의 다른 글

Python 공부 노트 11. Class  (0) 2014.01.03
Python 공부 노트 11. Module install  (0) 2014.01.02
Python에서 Open API 호출하기  (0) 2013.11.22
Django에서 static file (css,img 사용하기)  (0) 2013.11.21
Django Template  (0) 2013.11.21
Django Hello World  (0) 2013.11.21

django는 모듈화가 잘된건지. 웹개발에 최적화 된건지

여하간, tomcat처럼 디렉토리에 이미지나 CSS를 넣는다고 찾아지지 않는다.


(html) templates 처럼 특정 디렉토리를 생성하고 setting.py 파일에 지정해줘야 한다


setting.py에서

STATIC_URL = '/static/' 

해주고


각 app 디렉토리 밑에 /static이란 디렉토리를 만들어준다.

사용할 때는 load staticfiles를 불러준후에 경로를 다음과 같이 지정해주면 된다.


{% load staticfiles %}

this is group home

<img src="{% static "img/logo_nav.png" %}">


※ static file 경로 지정 방법 -https://docs.djangoproject.com/en/1.6/howto/static-files/


저작자 표시
신고

Django Template

프로그래밍/Python | 2013.11.21 02:07 | Posted by 조대협


Django의 MVC 구조


원본- littlegreenriver.com

Template 란?


Template은 쉽게 이야기 하면 jsp 파일과 같다고 보면된다.

template은 string으로 파일에서 로딩할 수 도 있고 몇개의 notation을 통해서 구성된다.

마치 JSP의 <% %> 처럼

time.html 파일이 다음과 같을때 

current time is {{ current_time }}


이는 

current time is <%=current_time%> (JSP에서)와 같은 의미라고 보면된다.

실제 view 모듈에서 이 템플릿을 렌더링 하는데, 이때, tempalte에 있는 인자들을 대입한다.

    template = loader.get_template('time.html')

    current_time = datetime.datetime.now()

    context = Context({'current_time' : current_time })

    return HttpResponse(template.render(context))


Context 객체는 인자를 넘기는 일종의 컨테이너라고 보면되고,

Template에 정해진 변수 이름에, 실제 값을 맵핑 시킨후에,

Template을 이 Context로 렌더링 한다.



Template 위치에 대해서.


https://docs.djangoproject.com/en/1.4/ref/templates/api/#loader-types

django.template.loaders.app_directories.Loader

Loads templates from Django apps on the filesystem. For each app in INSTALLED_APPS, the loader looks for a templates subdirectory. If the directory exists, Django looks for templates in there.


This means you can store templates with your individual apps. This also makes it easy to distribute Django apps with default templates.


템플릿을 로딩하는 방법은 여러가지 Loader 설정에 따라 변경할 수 가 있는데,

그중에서 filesystemLoader와 app_directories.loader가 디폴트 설정되어 있다.

이때, app_directories.loaderㅢ 경우에는 app directory 아래의 /templates/ 디렉토리에서 template을 찾는다.


#views.py - mysite/reader/views.py

from django.http import HttpResponse

from django.template  import Context, loader

import datetime



def what_time_is_it(request):

    template = loader.get_template('time.html')

    current_time = datetime.datetime.now()

    context = Context({'current_time' : current_time })

    return HttpResponse(template.render(context))


이파일은 mysite라는 프로젝트의 reader라는 애플리케이션이다.

위의 파일 경로가 mysite/reader/views.py 이다

template의 파일명만 지정했는데, 이 경우

mysite/reader/templates/time.html을 찾게 된다.


Template 사용시 Dictionary 접근 방법

JSON을 변환하여 dictionary를 접근하면, 일반 python code에서

item['name']['firstname'] 이었다면

Template에서는 item.name.firstname 으로 해야 한다.


참고 : https://docs.djangoproject.com/en/1.4/ref/templates/api/#loader-types



저작자 표시
신고

Django Hello World

프로그래밍/Python | 2013.11.21 00:20 | Posted by 조대협

http://www.djangobook.com/en/2.0/chapter03.html

Django 설치후 django-admin.py startprojec Yurryt로 사이트 만들고 (Yurry 라는 프로젝트가 만들어짐)

※ 참고 : Yurry 디렉토리안에는 urls.py, settings.py,_init_.py 등의 파일이 들어 있음. ../Yurry에 manage.py 파일등이 들어 있음

Yurry/views.py 라는 파일을 만듬

from django.http import HttpResponse


def hello(request):

    return HttpResponse("Hello world")

간단하게 Hello World를 Print Out하는 코드

그 다음 Yurry/urls.py에

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

from Yurry.views import hello


urlpatterns = patterns('',


   url(r'^hello/$', hello),


)

후에 Django start up 한후 http://localhost:8000/hello 라고 치면 Hello World가 나옴


만약 다른 Application으로 application 생성후, Yurry/setting.py 파일에서 INSTALLED_APPS를 다음과 같이 수정. App 이름이 reader라고 가정. 


INSTALLED_APPS = (

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    "reader"

)

reader/views.py를 만든후

내용은 위의 views.py와 똑같이 코딩한후, Yurry/urls.py 에 다음과 같이 추가


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

from Yurry.views import hello

from reader.views import hello_reader

#from django.contrib import admin

#admin.autodiscover()


urlpatterns = patterns('',

    # Examples:

    # url(r'^$', 'Yurry.views.home', name='home'),

    # url(r'^blog/', include('blog.urls')),

    # url(r'^admin/', include(admin.site.urls)),

   url(r'^hello/$', hello),

   url(r'^reader/$',hello_reader),

)

http://localhost:8000/reader 로 접속하면 나옴


저작자 표시
신고


초경량 Python 웹서버 bottle

MVC 예제


Controller 파일 구현 

/controller.py

import bottle

 

mythings = ['apple','orange','banana','peach']

 

@bottle.route('/')

def home_page():

    fruit = bottle.request.get_cookie("fruit")

    return bottle.template("hello_world",username="Andrew",things=mythings,like=fruit)

               

@bottle.post('/favorite_fruits')

def favorite_fruits():

    fruit = bottle.request.forms.get('fruit')

    if(fruit == None or fruit==""):

        fruit="No Fruit Selected"

    bottle.response.set_cookie('fruit',fruit)

    return bottle.template("fruit.tpl",{'fruit':fruit})

 

bottle.debug(True)

bottle.run(host='localhost',port=8080)


 

TBL 파일들은 템플릿으로, Python 변수는 {{ }}로 표현 (cf. jsp에서 <%=xx %>)

파이썬 로직은 %로 표현 (cf. jsp에서 <% %>)


/hello_world.tpl

<html>

<body>

Welcome {{username}}<br/>

You like <b>{{like}}</b>

<p>

<ul>

%for thing in things:

<li>{{thing}}</li>

%end

</ul>

<form action="/favorite_fruits" method=POST>

    What fruit do you like ?

    <input type="text" name="fruit" size=20 value="">

    <input type="submit" value="submit">

</form>

</body>

</html>


/fruit.tpl

<body>

Your like {{fruit}}

</body> 


실행 예




 

저작자 표시
신고



Bottle은 Python 기반의 초경량 웹서버이다.

Python 쪽에서는 Django등을 많이 사용하고 있지만, 설치도 쉽고, 가볍고 해서, 특정 목적이나 가벼운 테스트 웹 애플리케이션 개발등에는 충분히 활용이 가능하다.

(자바의 Jetty 와 같은 느낌?)


1. easy_installer에 설치

먼저 bottle을 설치하려면, installer부터 설치하는 것이 수월하다. python은 linux의 yum이나 rpm , 또는 Java의 maven과 유사하게 Pypi(Python Package Index - https://pypi.python.org/pypi ) 라는 툴을 제공한다. 


먼저 https://pypi.python.org/pypi/setuptools#windows 에서 ez_setup.py를 다운로드 받아서 실행한다



실행이 끝나면 ${Python 설치디렉토리}/Scripts/easy_install.exe 가 설치 된다.


2. bottle 설치

easy_install bottle 을 실행하면 bottle 라이브러리가 설치된다.



3. 간단한 애플리케이션 제작

bottle이 설치되었으면 간단한 애플리케이션을 만들어보자

아래 hello_world.py


import bottle

 

@bottle.route('/')

def home_page():

    return "hello world\n"

 

@bottle.route('/testpage')

def test_page():

    return "this is test page"

 

bottle.debug(True)

bottle.run(host='localhost',port=8080)


4. 실행

%python hello_world.py



다음으로 브라우져에서 http://localhost:8080/testpage 로 접근하면 다음과 같은 결과를 얻을 수 있다.



저작자 표시
신고

http://pds3.egloos.com/pds/200611/26/16/capistrano_niceview.pdf 여기 정리가 잘되어 있네요.

Fabric과 비슷하게 SSH 기반으로 작동하는 도구입니다.

위의 PT에 스크립트 작성하는 전체적인 흐름이 잘 정의 되어 있어서, Fabric 사용할때도 비슷하게 참조할 수 있겠습니다.


저작자 표시
신고

Fabric을 이용한 간단한 Tomcat deploy

프로그래밍/Python | 2013.01.29 18:46 | Posted by 조대협

Tomcat war deploy시, 가장 이상적인 방법은 

tomcat stop > copy war > start 순서이다.

아래는 간단하게 Python 기반의 Fabric을 이용하여, EC2상에서 pem (SSH)를 이용하여, Host들에 deploy하는 과정을 정의함


#fabfile.py

from fabric.api import run,env,execute,task

from fabric.operations import local,put


def tomcat_cluster():

        env.user ='root'

        env.hosts=['host1.server.com','host2.server.com'] # list of server setting

        env.key_filename='~/pem/pemfile.pem' # pem file


def hostname():

        run('uname -a')


def start():

        run('/etc/init.d/tomcat6 start')  # tomcat instance stop


def stop():

        run('/etc/init.d/tomcat6 stop') # tomcat instance stop


def copy():

        put('./dummy.war','/root/war') # file copy


def deploy(): 

        execute(stop)

        execute(copy)

        execute(start)

해당 파일을 fabfile.py에 저장후에

%fab tomcat_cluster deploy

해주면 아래와 같은 순서로 수행됨

host1.stop()

host1.copy()

host1.start()

host2.stop()

host2.copy()

host2.start()


기타 참고할만한 명령어
- sudo
- get : 파일 copy 해옴 
- local : local machine에서 명령어 수행
- with cd('{dir}') : 특정 디렉토리를 베이스로 명령어등을 수행할때 사용


※ 참고 : 외부에서 Host 명을 dynamic하게 받는 방법

--------------------------------

외부에서 host list 받는 방법

def deploy(lookup_param):

    # This is the magic you don't get with @hosts or @roles.

    # Even lazy-loading roles require you to declare available roles

    # beforehand. Here, the sky is the limit.

    host_list = external_datastore.query(lookup_param)

    # Put this dynamically generated host list together with the work to be

    # done.

    execute(do_work, hosts=host_list)

    

실행할때는

$ fab deploy:app


------ 또는 -----------

# Marked as a publicly visible task, but otherwise unchanged: still just

# "do the work, let somebody else worry about what hosts to run on".

@task

def do_work():

    run("something interesting on a host")


@task

def set_hosts(lookup_param):

    # Update env.hosts instead of calling execute()

    env.hosts = external_datastore.query(lookup_param)

    

$ fab set_hosts:app do_work

One benefit of this approach over the previous one is that you can replace do_work with any other “workhorse” task:


$ fab set_hosts:db snapshot

$ fab set_hosts:cassandra,cluster2 repair_ring

$ fab set_hosts:redis,environ=prod status


저작자 표시
신고

Python Fabric Install

프로그래밍/Python | 2013.01.28 18:55 | Posted by 조대협

AWS EC2 (Amazon Linux 기준)


1. Python install (dev package로 설치)

(반드시 dev package가 설치되어 있어야지, pycrypto 설치시 에러가 나지 않음. pycrptyo는 encryption 관련 라이브러리로 C 라이브러리를 사용하는데, 컴파일중, python.h를 사용한다. 이 헤더 파일은 dev package안에 포함되어 있음)


- yum install python-devel 


2. pip install

$ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py

$ [sudo] python get-pip.py


3. gcc가 인스톨 (pycrypto 설치를 위해서 필요함) 

yum install gcc


4. fabric install


pip install pycrypto fabric


5. 설치 확인


from fabric.api import run


def host_type():

    run('uname -s')


저작자 표시
신고

Admin 메뉴 추가 하기

setting.py에서

- admin 항목 uncomment 처리. INSTALLED_APPS에서 admin 모듈을 uncomment 처리하면됨

- 다음으로 manage.py에서 syncdb 처리 (app이 새로 등록되었으니 데이타 베이스 테이블 생성)


urls.py에서 

- admin url을 오픈해주기 위해서 admin 기능 관련 코드 uncomment 처리


그후 django 서버 기동하고 http://xxxx//admin 으로 로그인 하면됨.

로그인시 id/passwd는 처음에 manage.py syncdb 할때 넣었던 값으로 함.

이 admin 화면에서는 사용자 관리, 그룹 관리, 권한 관리등의 기본적인 기능들을 제공한다.


Admin 메뉴에 App admin 기능 추가 하기

django는 기본적으로 admin 기능을 제공하는데, 이 admin 기능에서는 해당 app의 model을 기반으로 UI를 자동 생성해준다.

예를 들어 poll(설문조사) 애플리케이션에서 Poll Model Class를 생성 관리할 수 있는 UI를 자동으로 만들어준다.

- ${app}디렉토리 아래 admin.py를 만들고

- 안에 다음과 같이 admin에 해당 Model 객체를 등록해주면 된다.


from polls.models import Poll

from django.contrib import admin


admin.site.register(Poll)


그러면 해당 Model 객체의 생성자 필드를 채울 수 있는 UI가 자동으로 생성된다.

그 밖에, 해당 Model의 값을 List 형식으로 출력될때 필드를 정하거나, Filtering등의 기능을 정의할 수 있고, Model의 attribute 뿐만 아니라, Model에서 사용자가 구현한 method의 결과값을 출력하게 할 수 도 있다.






※ 주로 모델 객체의 값에 대한 CRUD 기능을 위주로, Admin 기능을 구성할 수 있게 되어 있다.


저작자 표시
신고

Python 공부 노트 9. - Multi thread

프로그래밍/Python | 2013.01.23 21:09 | Posted by 조대협




http://www.tutorialspoint.com/python/python_multithreading.htm


import threading


class ThreadClass(threading.Thread):

def run(self):

# business logic

..

# lock acquire

threadLock.acquire()

...

# free lock to release 

threadLock.release()

threadLock = threading.Lock()


# create new thread

thread1 = ThreadClass()

thread2 = ThreadClass()

thread1.start()

thread2.start()


저작자 표시
신고

Django는 기본적으로 MVC 모델을 가지고 있고, DB 접근에 대해서는 OR Mapper와 같은 기능을 model 기능을 이용해서 제공한다.  

사실 최적화 정도는 조금 고려해봐야 겠지만, 기본적인 사용 방법은 다음과 같다.


==

python manage.py syncdb

- setting.py를 참고로 하여, default table을 데이타베이스에 생성


python startapp {appname}

- 새로운 app을 생성함. 

- 생성후에는 setting.py에 가서, INSTALLED_APPS 부분에 생성한 app이름을 넣어줘야 컨테이너가 인식함

INSTALLED_APPS = (

   'django.contrib.auth',

   'django.contrib.contenttypes',

   'django.contrib.sessions',

   'django.contrib.sites',

   'django.contrib.messages',

   'django.contrib.staticfiles',

   # Uncomment the next line to enable the admin:

   # 'django.contrib.admin',

   # Uncomment the next line to enable admin documentation:

   # 'django.contrib.admindocs',

   'polls' <-- 요렇게 추가

)

- models.py 파일에 데이타 클래스를 정의

  Value Object을 정의하는데, Java와는 다르게, Data Type이나 객체간 relationship도 지정함

  

class Choice(models.Model):

    poll = models.ForeignKey(Poll) <-- Poll Class에 대한 FK

    choice = models.CharField(max_length=200) <-- varchar(200)

    votes = models.IntegerField() <-- Int type

    

- 마지막으로 model.py sql {appname} 해주면, 해당 DBMS에 테이블을 생성 SQL문을 만들어서 보여줌 (실제 실행은 안됨)

  테이블명은 {appname}_{modelclass명} 식으로 생성됨

  예를 들어 appname이 polls이고, VO가 위에 클래스 명처럼 Choice일 경우 테이블은 아래와 같은 형태로 생성됨

  CREATE TABLE "polls_choice" (

    "id" integer NOT NULL PRIMARY KEY,

    "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),

    "choice" varchar(200) NOT NULL,

    "votes" integer NOT NULL

  );

  테이블명과 Index등의 생성 규칙

The exact output will vary depending on the database you are using.

Table names are automatically generated by combining the name of the app (polls) and the lowercase name of the model -- poll and choice. (You can override this behavior.)

Primary keys (IDs) are added automatically. (You can override this, too.)

By convention, Django appends "_id" to the foreign key field name. (Yes, you can override this, as well.)

The foreign key relationship is made explicit by a REFERENCES statement.

It's tailored to the database you're using, so database-specific field types such as auto_increment (MySQL), serial (PostgreSQL), or integer primary key (SQLite) are handled for you automatically. Same goes for quoting of field names -- e.g., using double quotes or single quotes. The author of this tutorial runs PostgreSQL, so the example output is in PostgreSQL syntax.

The sql command doesn't actually run the SQL in your database - it just prints it to the screen so that you can see what SQL Django thinks is required. If you wanted to, you could copy and paste this SQL into your database prompt. However, as we will see shortly, Django provides an easier way of committing the SQL to the database.


- insert는 객체를 만든후에, object.save()를 하면됨

- select는 {ClassName}.objects.get({key}={value}) 를 하면 select x from ClassName where {key}={value} 와 같은 효과

  {ClassName}.objects.filter 하면 조건 검색

- 해당 object.delete() 하면 삭제


reference https://docs.djangoproject.com/en/1.4/intro/tutorial01/


저작자 표시
신고

Python 공부 노트 7. - Django 설치

프로그래밍/Python | 2013.01.22 00:26 | Posted by 조대협

설치

Python 설치 후, Django 다운로드 https://www.djangoproject.com/download/ 

후에, 압축 풀고

 > python setup.py install


설치 확인

>>> import django
>>> print(django.get_version())
1.6

웹사이트 생성

django-admin.py startproject mysite

dajngo-admin.py는 C:\dev\Python27\Scripts 에 있음

해당 디렉토리에 웹사이트 관련 디렉토리 생성됨 (일종의 Tomcat Home, WebLogic Domain Home 디렉토리 같은 개념, 바이너리는 python 디렉토리 아래에 있음)


웹사이트 실행

python manage.py runserver


참고 자료 - https://docs.djangoproject.com/en/dev/intro/tutorial01/


저작자 표시
신고

Python 공부 노트 6. - Logging

프로그래밍/Python | 2013.01.21 19:21 | Posted by 조대협

http://docs.python.org/2/howto/logging-cookbook.html


# Add the log message handler to the logger

handler = logging.handlers.RotatingFileHandler(

              LOG_FILENAME, maxBytes=20, backupCount=5)

              

my_logger.addHandler(handler)

my_logger.debug('log message here....')


Logger

: 일종의 identifier로, 애플리케이션 마다 logger를 정하 수 있음


handler

: 파일 핸들러, 소켓 핸들러,  Rotating 파일 핸들러등,스트림 핸들러(Console 등)

※ DB Handler는 없는 듯 하고, 소켓 핸들러를 이용하면, 분산 시스템에서 중앙 집중화된 Logger를 만들 수 있음

(단, 로그 서버가 별도로 있는게 아니기 때문에, 분산 환경용 로거는 만들기 나름)


formater

: 핸들러 마다 붙일 수 있음


logging 메서드

: debug,info,warn,error,critical

: setLevel로 로그 출려 레벨 정함


단순 예제


import logging


logger = logging.getLogger("logging_sample")

logger.setLevel(logging.DEBUG)

# file log handler

fh = logging.FileHandler("/temp/python.log")

fh.setLevel(logging.ERROR)

# console log handler

ch = logging.StreamHandler()

ch.setLevel(logging.DEBUG)

#create formmater

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setFormatter(formatter)

fh.setFormatter(formatter)

logger.addHandler(ch)

logger.addHandler(fh)


logger.debug("this is debugging")

logger.info("this is info")



저작자 표시
신고

Python 공부 노트 5. - 단위 테스트

프로그래밍/Python | 2013.01.21 00:10 | Posted by 조대협

단위테스트는 자바의 JUnit과 사상이 기본적으로 같음


import unittest


class SimpleTest(unittest.TestCase):

        @classmethod

        def setUpClass(cls):

            print("set up class")

            return

        

        @classmethod

        def tearDownClass(cls):

            print("tearDown class")

            

        def setUp(self):

            print("this is setup")

            return

            

        def tearDown(self):

            print("this is tear down")

            return

            

        def testSimple(self):

            self.assert_(1==2, "my assert failed")

            

        def testSecond(self):

            self.assertEqual(2, 2, "equal fails")

 

if __name__ == '__main__':

    unittest.main()           

#suite = unittest.TestLoader().loadTestsFromTestCase(SimpleTest)

#unittest.TextTestRunner(verbosity=2).run(suite)

  • setUpClass : 해당 클래스에서 테스트 시작시 한번만 사용됨. 초기 테스트 값 로딩이나 초기화
  • setUp : 테스트케이스 실행될때 마다 사용됨
  • tearDownClass: 해당 테스트 클래스 종료시 한번만 사용됨. (테스트 종료시 자원 정리등)
  • tearDown : 각 테스트 케이스 종료시 마다 사용됨
  • 테스트 케이스는 testXXX 로 시작됨
- 간단하게 unittest.main() 호출해서 시작할 수 도 있고, 별도의 TestSuite을 만들어서 테스트 가능
- 자체 프레임웍으로 LoadTest도 가능 - http://docs.python.org/2/library/unittest.html#load-tests-protocol
- Hudson (Jekins)연동은 Python을 이용하여 수행 - http://www.jython.org/jythonbook/en/1.0/TestingIntegration.html

아예 부하 테스트는 multi-mechanize를 이용해 가능. (작년에 보던 놈인데, 이제 파이썬 볼줄 아니까는 테스트 할 듯 있을듯)
http://testutils.org/multi-mechanize/
국내에서는 nGrinder가 많이 사용됨



저작자 표시
신고

RDBMS 프로그래밍시에는 해당 RDBMS에 대한 드라이버(모듈을) import해야 한다. sqlite의 경우는 이미 들어가 있다. 아래는 가장 기본적인 코드 이다.

import sqlite3


conn = sqlite3.connect("datafile")

cursor = conn.cursor()

cursor.execute("drop table test")

cursor.execute("create table test (name text,count integer)")

cursor.execute("insert into test(name,count) values('Terry',1)")

cursor.execute("insert into test(name,count) values('Cath',2)")

conn.commit()

result = cursor.execute("select * from test")

while True:

    row = result.fetchone()

    if row == None:

        break

    print row[0],row[1]

conn.close()

데이타 베이스 프로그래밍 순서

  1. 먼저 import를 통해서, 해당 데이타베이스를 접근하기 위한 모듈을 import한다.
  2. 해당 모듈.connect를 이용하여 데이타 베이스 connection을 연결한다. dbms에 따라서 connection string이 다르다. sqlite의 경우 파일 기반이기 때문에, 파일경로만 지정하면 되고, mysql의 경우에는 host,userid,userpasswd,dbms 식으로 기술해주면 된다.
  3. 다음은 cursor를 connection으로 부터 생성한다.
  4. cursor.execute를 통해서 query를 실행한다.
  5. select의 경우에는 result를 받은후에
    • - fetchall()의 경우 결과를 모두 리턴
    • - fetchone()의 경우 하나의 row를 리턴
    • - fetchmany(num rows)의 경우 rows의 숫자 만큼 리턴을 한다.
  6. conn.commit을 이용하여 transaction을 commit한다.
  7. 마지막으로 사용한 connection을 close한다.
mysql 데이타베이스도 다르지 않다. (정말 쉽다.)

다음은 약간 더 진보된 코드로, 데이타베이스에 대한 에러 핸들링을 포함하고 있다.

import sqlite3

try:
    conn = sqlite3.connect("datafile")
    cursor = conn.cursor()
    cursor.execute("drop table test")
    cursor.execute("create table test (name text,count integer)")
    cursor.execute("insert into test(name,count) values('Terry',1)")
    cursor.execute("insert into test(name,count) values('Cath',2)")
    conn.commit()
    result = cursor.execute("select * from test")
    while True:
        row = result.fetchone()
        if row == None:
            break
        print row[0],row[1]
except sqlite3.Error, e:
    if conn:
        conn.rollback
finally:
    if conn:
        conn.close()

기본적으로 sqlite 라이브러리가 포함되어 있는게 마음에 든다. 간단한 tutorial이나, 간단한 dbms 프로그래밍의 경우 별도의 라이브러리 설치가 필요없다.




저작자 표시
신고