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


Archive»


 
 

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 를 참고하였음


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 로 접근하면 다음과 같은 결과를 얻을 수 있다.



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 기능을 구성할 수 있게 되어 있다.


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/


http://showmedo.com/videos/video?name=1100000&fromSeriesID=110
파이썬은 대충 감만 잡았고, 실제 코딩을 해봐야할것 같은데, 현재는 프로젝트내에서 쓸일은 없으니 간단한 웹프로그래밍으로 먼저 접근.
인도 사람이 만든 튜토리얼 같은데... 시간날때 한번 따라해봐야 겠다. 먼저 django 서버 부터 인스톨 해야 겠네..
TAG Django, python