- API 란? API-Best-Practices-ebook-2016-12.pdf

- 네이버 API 신입사원 교육: https://github.com/quki/web-api-practice

- django 예제: https://github.com/jihyungSong/pyengine

- API 설계시 참조할 구조: http://catmaid.readthedocs.io/en/stable/contributing.html


'TF' 카테고리의 다른 글

[Research] django high availability  (0) 2017.06.28
[Research] openstack  (0) 2017.06.27
[Research] Quota/Spike difference  (0) 2017.06.27
[Research] 스파이크( spike)  (0) 2017.06.27
[Define] TF 란?  (0) 2017.06.27

태스크포스 (task force)


- 프로젝트 팀(project team)이라고도 한다. 태스크포스는 각 전문가간의 커뮤니케이션과 조정을 쉽게 하고, 

밀접한 협동관계를 형성하여 직위의 권한보다도 능력이나 지식의 권한으로 행동하여 성과에 대한 책임도 명확하고 행동력도 가지고 있다. 

일정한 성과가 달성되면 그 조직은 해산되고, 환경변화에 적응하기 위한 그 다음 과제를 위하여 새로운 태스크포스가 편성되어 조직 전체가 

환경변화에 대해 적응력 있는 동태적 조직의 성격을 가진다. 태스크포스는 시장이나 기술 등의 환경변화에 대해서 적응력을 갖는 

조직형태일 뿐만 아니라, 새로운 과제에의 도전.책임감.달성감.단결심 등을 경험하는 기회를 구성원들에게 제공하고, 

구성원의 직무만족을 높이는 효과가 있다.


R&D (Research and development)


연구개발 또는 간단히 R&D(Research and development)는 경제 협력 개발 기구에 따르면 "인간, 문화, 사회의 지식을 비롯한 지식을 증강하기 

위한 창조적인 일이자 새로운 응용물을 고안하기 위한 지식의 이용"을 가리킨다.

연구개발은 과학적이거나 특정한 기술 개발 지향적이며, 또 간헐적으로 기업, 정부 활동으로 수행되기도 한다.

'TF' 카테고리의 다른 글

[Research] django high availability  (0) 2017.06.28
[Research] openstack  (0) 2017.06.27
[Research] Quota/Spike difference  (0) 2017.06.27
[Research] 스파이크( spike)  (0) 2017.06.27
[Research] API (Application Programming Interface)  (0) 2017.06.27

장고앱을 만드는 순서가 좀 애매한 부분이 있다 ...


"urls 패턴정의가 먼저냐 뷰생성이 먼저냐 ?" 인데...


urls 패턴을 정의하려면 뷰이름이 필요하고 

뷰를 만들고 호출하려면 urls 패턴이 먼저 정의 되야하고... 


순서가 애매하다 보니 자주 실수 하는것이 urls 패턴에 정의된 뷰이름과 실제 작성한 뷰함수이름이 틀려서 에러가 발생하거나 

뷰함수만 작성하고 urls 패턴을 정의 하지 않아서 페이지가 안보이는 경우가 있다. 약간의 삽질일 수 있겠다.

 

그래서 장고가 익숙하지 않는 사람이라면(나) 빈페이지라도 동작 할 수 있는 구조를 만들어 페이지 열림을 확인하고 

나머지 코딩을 진행해하는 것이 좋다.


1. 일단 글목록 뷰 테스트를 위한 앱을 하나 생성하자

(개인적으로다가 manager.py 에서 startapp param 으로 인덱스뷰이름도 추가적으로 받아서 자동으로 views.py, urls.py 파일을 만들어 줬음 좋겠다 -_-;)

]# manager.py startapp catalog index 

위처럼 커맨드를 입력하면 아래처럼 수행되게...


]# cd /home/myproject
]# /usr/local/python3.4/bin/python3 manage.py startapp catalog
]# tree /home/myproject
/home/myproject
├── myproject
│?? ├── __init__.py
│?? ├── settings.py
│?? ├── urls.py
│?? └── wsgi
├── catalog
│?? ├── __init__.py
│?? ├── admin.py
│?? ├── apps.py
│?? ├── migrations
│?? │?? ├── __init__.py
│?? ├── models.py
│?? ├── tests.py
│?? └── views.py
└── manage.py

]# cat <<EOF > catalog/urls.py
from django.conf.urls import url
from .views import index

urlpatterns = [
    url(r'^$', index),
]
EOF

]# cat <<EOF > catalog/views.py
from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello world")
EOF


2. catalog 앱을 프로젝트에서 인식 할 수 있도록 INSTALLED_APPS 에 추가한다.

]# vi myproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'catalog',
]


3. catalog 앱에서 사용할 catalog/urls.py 파일을 프로젝트 myproject/urls.py 에 include 해준다

]# vi myproject/urls.py
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^catalog/', include('catalog.urls')),
]

/usr/local/python3.4/bin/python3 manage.py runserver 0.0.0.0:8080

   

4. django 를 실행하고  페이지 열림을 확인한다.

http://127.0.0.1:8080/catalog/



5. 리스트페이지에서 보여줄 모델을 작성해보자

]# cat <<EOF > catalog/models.py
from django.db import models

class GuestBook(models.Model):

    auth = models.CharField(max_length=20)
    title = models.CharField(max_length=100)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['-id']
EOF

]# /usr/local/python3.4/bin/python3 manage.py makemigrations catalog
]# /usr/local/python3.4/bin/python3 manage.py migrate


6. GuestBook 모델에 데이터를 넣어보자

/usr/local/python3.4/bin/python3 manage.py shell
>>> from catalog.models import GuestBook
>>> for i in range(1,1001):
...     GuestBook.objects.create(title='{} 째글입니다'.format(i), auth='관리자', content='{} 째 글입니다'.format(i))
>>> GuestBook.objects.all()


7. GuestBook 모델을 갖고 오는 뷰와 템플릿을 작성해보자.

cat <<EOF > catalog/views.py
> from django.shortcuts import render
> from django.http import HttpResponse
> from .models import GuestBook
> def index(request):
>     guest_book_list = GuestBook.objects.all()
>     return render(request, 'catalog/index.html', {'guest_book_list': guest_book_list})
> EOF

cat <<EOF > catalog/templates/catalog/index.html 
<!DOCTYPE html>
<html lang="en">
<head>
  <title>GuestBook Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">
  <h2>GuestBook</h2>
  <ul class="list-group">
    {% for guest_book in guest_book_list %}
      <li class="list-group-item">{{ guest_book.title }}</li>
    {% endfor %}
  </ul>
</div>

</body>
</html>
EOF



8. 위그림처럼 모든 게시물이 쭉 출력이 되므로 django의 Paginator 를 사용하여 페이징을 붙여 보자.

# catalog/views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import GuestBook
from django.core.paginator import Paginator

def index(request):
    """
    GET 방식으로 page 변수를 받는다.
    """
    page = request.GET.get('page''1')
    if len(page) == 0: page = '1'
    if type(page) != int : page = int(page)

    """
    guestbook queryset 얻는다.

    """

    guest_book_list = GuestBook.objects.all()

    """
    guest_book_list 를 10개씩 paging 한다.
    """
    num = 10
    guest_book_paginator = Paginator(guest_book_list, num)
    guest_book_page = guest_book_paginator.page(page)

    """
    현재페이지가 속해있는 페이지구룹(리스트)를 구하여 페이지네비게이터로 사용한다.
    page 페이지와 제일 가까운 num 의 배수를 구하여 시작페이지인덱스를 구하고 
    시작페이지인덱스에 num 을 더하여 마지막페이지인덱스를 구한다.
    """
    for i in reversed(range(1,page+1)):
        if i%num == 1:
            start_page_index = i
            break
    end_page_index = min(start_page_index + num, max(guest_book_paginator.page_range)+1)
    page_list = range(start_page_index, end_page_index)

    """
    위 페이지네비게이터를 구하는 방법이 마음에 안든다면 간단한 수식을 이용해서도 구현할수 있다.
    참조: https://jupiny.com/2016/11/22/limit-pagination-page-numbers-range/

    max_index = len(guest_book_paginator.page_range)
    start_index = int((page - 1) / num) * num
    end_index = start_index + num
    if end_index >= max_index:
        end_index = max_index
    page_list = guest_book_paginator.page_range[start_index:end_index]
    """
    return render(request, 'catalog/index.html', {'guest_book_list': guest_book_page, 'page_list': page_list})


# catalog/templates/catalog/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <title>GuestBook Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">
  <h2>GuestBook</h2>
  <ul class="list-group">
    {% for guest_book in guest_book_list %}
      <li class="list-group-item">{{ guest_book.title }}</li>
    {% endfor %}
  </ul>
  <ul class="pagination">
    {% if guest_book_list.has_previous %}
      <li>
        <a href="?page={{ guest_book_list.previous_page_number }}">
          <span>Previous</span>
        </a>
      </li>
    {% else %}
      <li class="disabled">
        <a href="#">
          <span>Previous</span>
        </a>
      </li>
    {% endif %}

    {% for page in page_list %}
      <li {% if page == guest_book_list.number %}class="active"{% endif %}>
        <a href="?page={{ page }}">{{ page }}</a>
      </li>
    {% endfor %}

    {% if guest_book_list.has_next %}
      <li>
        <a href="?page={{ guest_book_list.next_page_number }}">
          <span>Next</span>
        </a>
      </li>
    {% else %}
      <li {% if not guest_book_list.has_next %}class="disabled"{% endif %}>
        <a href="#">
          <span>Next</span>
        </a>
      </li>
    {% endif %}
  </ul>
</div>

</body>
</html>


결과페이지

http://sdevvm001.cafe24.com:8080/catalog/ 

+ Recent posts