Django 기본 04 - Class Based View 응답예시 (JSON, 템플릿)

|

AskDjango 수업을 듣고 중요한 내용을 정리하였습니다.

Class Based View (CBV)

  • django.views.generic : 뷰 사용패턴을 일반화 시켜놓은 뷰의 모음
  • .as_view() : 클래스함수를 통해, FBV를 생성해주는 클래스
  • FBV로 구현한 view는 CBV로도 구현 할 수는 있다. 하지만 CBV는 패턴화 되어 있는 뷰를 처리할 때 효율적으로 처리 할 수 있다. (적은 코드로 뷰를 구현할 수 있음)
  • 공부할 때 처음에는 함수기반 뷰(FBV) 로 구현을 많이 해보고 나서, 클래스기반 뷰(CBV)를 사용하는 것이 좋다. (FBV를 충분히 이해하지 않은 상태에서 CBV를 사용하면 나중에 코드가 산으로 갈 위험이 있다.)

FBV 예시

  1. 직접 문자열로 HTML 형식 리스폰스
  2. 템플릿을 통해 HTML 형식 리스폰스
  3. JSON 형식 리스폰스
  4. 파일 다운로드 리스폰스

직접 문자열로 HTML 형식 리스폰스

from django.http import HttpResponse
from django.views.generic import View

class PostListView1(View):
    def get(self, request):
        name = '공유'
        html = self.get_template_string().format(name=name)
        return HttpResponse(html)

    def get_template_string(self):
        return '''
                <h1> hello, </h1>
                <p>{name}</p>
                <p>반가워요</p>
                '''

post_list1 = PostListView1.as_view()

템플릿을 통해 HTML 형식 리스폰스

from django.views.generic import View, TemplateView

class PostListView2(TemplateView):
    template_name = 'dojo/post_list.html'

    def get_context_data(self):
        context = super().get_context_data()
        context['name'] = '공유'
        return context

post_list2 = PostListView2.as_view()

JSON 형식 리스폰스

from django.http import HttpResponse, JsonResponse
from django.views.generic import View, TemplateView

class PostListView3(View):
    def get(self,request):
        return JsonResponse(self.get_data(), json_dumps_params={'ensure_ascii': True})

    def get_data(self):
        return{
            'message' : '안녕 파이썬 장고',
            'items' : ['파이썬', '장고', 'AWS', 'Azure'],
        }

post_list3 = PostListView3.as_view()

Django 기본 03 - Function Based View 응답예시 (JSON, 파일다운, 템플릿)

|

AskDjango 수업을 듣고 중요한 내용을 정리하였습니다.

view

  • view / view 함수
  • URLConf에 매핑된 Callable Object
    • 파이썬에는 함수 이외에도 다양한 호출 가능한 객체가 존재함
    • 첫번째 인자로 HttpRequest 인스턴스를 받는다.
    • 필히 HttpResponse 인스턴스를 리턴 해야한다.
  • 크게 Function Based View (FBV)와 Class Based View (CBV)로 구분한다.

Fucntion Based View

FBV 예시

  1. 직접 문자열로 HTML 형식 리스폰스
  2. 템플릿을 통해 HTML 형식 리스폰스
  3. JSON 형식 리스폰스
  4. 파일 다운로드 리스폰스

FBV 예시1 - 직접 문자열로 HTML 형식 리스폰스

# myapp/views.py
from django.http import HttpResponse

def post_list1(request):
    name = '공유'
    return HttpResponse('''
                        <h1> hello, </h1>
                        <p>{name}</p>
                        <p>반가워요</p>
                        '''.format(name=name))

FBV 예시2 - 템플릿을 통해 HTML 형식 리스폰스

# myapp/views.py
from django.shortcuts import render

def post_list2(request):
    name = '홍철'
    return render(request, 'dojo/post_list.html', {'name': name})
<!-- myapp/templates/myapp/post.list.html -->

<h1>hello</h1>
<p>{{name}}</p>
<p>반가워요</p>

FBV 예시3 - JSON 형식 리스폰스

# myapp/views.py
from django.http import HttpResponse, JsonResponse

def post_list3(request):
    return JsonResponse({
        'message' : '안녕 파이썬 장고',
        'items' : ['파이썬', '장고', 'AWS', 'Azure'],
    }, json_dumps_params = {'ensure_ascii': True})
views
FBV의 json 형식 리스폰스
  • 크롬확장프로그램 JsonView 를 통해서 서버에서 전달한 Json 응답을 브라우저에서 읽기 쉽도록 표시

FBV 예시4 - 파일 다운로드 리스폰스

# myapp/views.py
import os
from django.http import HttpResponse

def excel_download(request):
    # 현재 프로젝트 최상위 (부모폴더) 밑에 있는 'scimagojr-3.xlsx' 파일
    filepath = os.path.join(settings.BASE_DIR, 'scimagojr-3.xlsx')
    filename = os.path.basename(filepath) # 파일명만 반환

    with open(filepath, 'rb') as f:
        response = HttpResponse(f, content_type='application/vnd.ms-excel')
        # 필요한 응답헤더 세팅
        response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)
        return response

# settings.py
# 현재 파일의 부모경로, 부모경로를 반환
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  • os.path.dirname(path) : 입력받은 파일/디렉터리의 경로를 반환
  • os.path.join(path1[,path2[,…]]) : 해당 OS 형식에 맞도록 입력 받은 경로를 연결
  • os.path.basename(path) : 입력받은 경로의 기본 이름(base name)을 반환한다. abspath() 함수와 반대되는 기능을 수행

level 3. 다음 큰 숫자

|

출처

문제

어떤 수 N(1≤N≤1,000,000) 이 주어졌을 때, N의 다음 큰 숫자는 다음과 같습니다.

N의 다음 큰 숫자는 N을 2진수로 바꾸었을 때의 1의 개수와 같은 개수로 이루어진 수입니다. 1번째 조건을 만족하는 숫자들 중 N보다 큰 수 중에서 가장 작은 숫자를 찾아야 합니다. 예를 들어, 78을 2진수로 바꾸면 1001110 이며, 78의 다음 큰 숫자는 83으로 2진수는 1010011 입니다. N이 주어질 때, N의 다음 큰 숫자를 찾는 nextBigNumber 함수를 완성하세요.

풀이 (python)

def nextBigNumber(n):
    num_of_one = str(bin(n)).count('1')
    for i in range(n+1,1000001):
        if str(bin(i)).count('1') == num_of_one:
            return i


#아래 코드는 테스트를 위한 출력 코드입니다.
print(nextBigNumber(78))

풀이과정

  1. 인자 N을 2진수로 변환
  2. 1의 갯수를 확인
  3. 10진수 N < x <= 1,000,000 사이의 숫자를 하나씩 2진수로 바꾸어 1의 갯수가 위의 2와 같다면, x를 리턴한다.

배운점

  • bin(), oct(), hex() 내장함수를 통해 정수를 각 2진수, 8진수, 16진수로 바꿀 수 있다.
  • str() 내장함수를 통해 인자를 문자열로 변환한다.
  • str.count(‘검색어’)를 통해서 해당 검색어의 갯수를 리턴한다.

170318_TIL

|

오늘 한 일

  • AskDjango 에서 정규표현식, URLConf 부분을 배웠다. urls.py 에서 사용하는 정규표현식과 인자를 받아오는 부분을 다시 한번 정리할 수 있어서 좋았다. 특히 ngrok를 사용해서 모바일로 개발 서버에 접속해서 테스트 할 수 있다는 점은 유용했다. 잘 정리해두고 나중에 활용해야지.
  • Swift3 & iOS10 강의를 듣기 시작했다. swift 기본 문법을 배웠는데 기존에 배운 자바스크립트, 파이썬에 비해서 좀 더 엄격하다는 인상을 받았다. 함수 선언시에 형을 같이 입력하고, Argument Labels 과 Parameter Names 이 존재한다는 점 때문에 그런 것 같다.

내일 할 일

Django 기본 02 - 파이썬 정규표현식, URLConf

|

AskDjango 수업을 듣고 중요한 내용을 정리하였습니다.

정규표현식 (Regular Expression)

  • 대부분의 개발 언어에서 지원
  • 문자열 검색, 치환을 간편하게 처리
  • 파이선3 는 re라는 모듈을 통해서 지원 - 라이브러리

정규표현식 예시

  • ^(시작), $(끝)을 사용하여 해당 패턴에 완전히 일치하는 것만 찾을 수 있다.
  • r(raw) 로 시작하여 이스케이프 문자를 한번 더 쓰지 않아도 된다. 자동 이스케이핑

예시

r"[0-9]{1,3}" or r"\d{1,3}" # 최대 3자리 숫자
r"010[1-9]\d{6,7}" #10자리 혹은 11자리 휴대폰번호
r"[ㄱ-힣]{2,3}" # 한글이름 2글자 혹은 3글자
r"이[ㄱ-힣]{1,2}" # 성이 "이"인 이름

1글자 패턴 예시

r"[0,1,2,3,4,5,6,7,8,9]" or r"[0-9]" or r"\d" # 숫자 1글자
r"[a-z]" # 소문자 1글자
r"[A-Z]" # 대문자 1글자
r"[a-zA-Z]" # 대소문자 1글자
r"[ㄱ-힣]" # 한글 1글자

반복횟수 지정

r"\d?" # 숫자 0회 또는 1회 (있거나 없거나)
r"\d*" # 숫자 0회 이상
r"\d+" # 숫자 1회 이상
r"\d{m}" # 숫자 m 글자
r"\d{m,n}" # 숫자 m글자 이상 n글자 이하 (m~n)

(참고) ipython 설치 및 실행

  • python을 터미널에서 사용할때 편리한 프로그램
$ pip3 install "ipython[notebook]" # 설치
$ ipython # 실행
$ python3 -m  IPython # 위 명령어로 동작하지 않을 경우

정규표현식 참고자료


URLConf

  • settings.py에 최상위 URLConf 모듈을 지정
  • 특정 URL과 뷰 매핑 list
  • Django 서버로 Http 요청이 들어올 때마다, URLConf 매핑 List 를 처음부터 끝까지 순차적으로 훝으며 검색
  • 매칭되는 URL Rule 을 찾지못했을 경우, 404 Page Not Found 응답을 발생
# settings.py
ROOT_URLCONF = 'mysite.urls' # 프로젝트/urls.py 파일

URLConf 정규표현식 매핑

예시1

# urls.py
url(r'^sum/(?P<x>\d+)/$', views.mysum)

# views.py
def mysum(request, x):
  return HttpResponse(int(x))
  • (?P) : 이 영역의 문자열에 정규표현식을 적용해서
  • \d+ : \d+ 패턴에 부합된다면
  • <x> : x 라는 변수명으로 인자를 view.sum 으로 넘기겠다.
  • 인자로 넘겨받은 값들은 모두 문자열 타입

예시2

# 인자 2개
url(r'^sum/(?P<x>\d+)/(?P<y>\d+)/$', views.mysum)

# views.py
def mysum(request, x, y):
return HttpResponse(int(x) + int(y))

# 인자 3개
url(r'^sum/(?P<x>\d+)/(?P<y>\d+)/(?P<z>\d+)/$', views.mysum)
# views.py
def mysum(request, x, y, z):
    return HttpResponse(int(x) + int(y) + int(z))

# 하나의 뷰에 3개의 url 연결
url(r'^sum/(?P<x>\d+)/(?P<y>\d+)/(?P<z>\d+)/$', views.mysum)
url(r'^sum/(?P<x>\d+)/(?P<y>\d+)/$', views.mysum)
url(r'^sum/(?P<x>\d+)/$', views.mysum)
# views.py
def mysum(request, x, y=0, z=0):
  return HttpResponse(int(x) + int(y) + int(z))

예시3

# 인자가 여러개인 경우
url(r'^sum/(?P<numbers>[\d/]+)/$', views.mysum)

# views.py
def mysum(request, numbers):
    return HttpResponse(sum(map(int,numbers.split('/'))))

# 나이, 이름 인자 받기
url(r'^hello/(?P<name>[ㄱ-힣]+)/(?P<age>\d+)$', views.hello)

# views.py
def hello(request, name, age):
    return HttpResponse('안녕하세요. {}. {}살이시네요'.format(name,age))