1. JSON & Http Resquest & Response & Httpie
- JSON
- Java Script Object Notation 의 약자
- 데이터 송수신을 자바스크립트의 문법으로 표현된 객체로 수행할 수 있게 만든 가벼운 문자열 데이터 표현식
- 자바스크립트를 사용하지 않아도 사용 가능하다!
- 웹에서는 Server와 Client 사이에는 여러 항목을 주고 받음. /구조를 나타내는 HTML /스타일을 표현하는 CSS /논리를 구현하는 Javascript
- 앞으로의 강의들은 데이터인 JSON 만 주고 받음!
- JSON 문법 형식
- Python 의 딕셔너리와 비슷한 구조
- name : value
- 숫자, 문자(열), Boolean, 배열, 객체 등으로 구성 가능
- JSON 데이터를 보낼 때에는 직렬화(Serialization) 과정을 거쳐 JSON 데이터를 문자열로 바꾸어 상대방에게 보낸다.
- 데이터를 보낼 때에는 JSON -> 문자열로 / 데이터를 받을 때에는 문자열 -> JSON으로 바꾸어 받는다.
json_example = {
"string_name": "something",
"number_name": 3,
"null_name": null,
"bool_name": true
}
- Python에서 JSON 사용하기
- Python 딕셔너리 자료형을 반환해보자
import json //Json을 처리하는 라이브러리를 제공
diary = {
"id": 3,
"title": “멋쟁이사자처럼”,
"body“: “2학기도 파이팅”
}
print(diary)
//{‘id’: 3, 'title': ‘멋쟁이사자처럼’, ‘body’: ‘2학기도 파이팅’}
print(type(diary))
//<class ‘dict’>
- Dict to JSON
- JSON의 dumps 함수를 이용해 변환 진행
- 데이터를 송신할 때 사용할 수 있다.
- dic 이였던 자료형이 str로 변환
diary_s = json.dumps(diary)
print(diary_s)
//{‘id’: 3, 'title': ‘멋쟁이사자처럼’, 'body': ‘2학기도 파이팅’}
print(type(diary_s))
//<class ‘str’>
- JSON to Dict
- JSON 의 load 함수를 이용해 변환을 진행
- 데이터를 수신할 때 사용할 수 있다
- Str 자료형이 dict로 다시 변환되었음을 볼 수 있다.
diary_b = json.loads(diary)
print(diary_b)
//{‘id’: 3, 'title': ‘멋쟁이사자처럼’, 'body': ‘2학기도 파이팅’}
print(type(diary_b))
//<class ‘dict’>
Http Requsest & Response
- 정의
- Http란?
- 웹 상에서 통신을 주고 받을 수 있는 주체, Client와 Server 그 중, Server의 역할은 Request 를 가공해서 처리해주는 역할
- Web 상에서 지원하는 통신 규약을 Http
- 한마디로 정의한다면?
- HttpRequest : 요청에 대한 메타 정보를 가지고 있는 객체
- HttpResponse : 요청에 대한 메타 정보를 가지고 있는 객체
- Django 에서 Http Method
- Http란?
GET | POST |
빈 입력공간 가져와 | 입력한 내용 처리 |
URL에 데이터 정보 포함 | URL에 데이터 정보 포함 안함 |
▪ Django 에서 Rest FrameWork에서 Http Method
Method | 기능 |
GET | 요청받은 URL의 정보 검색하여 응답 |
POST | 요청된 자원을 생성(CREATE) |
DELETE | 요청된 자원 삭제 |
PATCH | 요청된 자원 일부 수정 |
OPTION | 웹 서버에 지원된 메소드 종류 확인 |
Django Rest FrameWork?
-> 장고 안에서 RESTful API 서버를 쉽게 구축할 수 있도록 도와주는 오픈 소스라이브러리
-Rest?
-> HTTP 의 URL과 HTTP Method(GET, POST, PUT, DELETE)를 사용해서
API 사용 가독성을 높인 구조화된 시스템 아키텍쳐(Framework)
-RESTful 아키텍쳐를 HTTP Method와 함께 사용해서 웹, 데스크탑 앱, 어플리케이션 까지 구동할 수 있는 서버를 만든다고 생각!
- Django Rest Framework API Server에서는 JSON을 주고 받음
- 서버 Response 종류
- 1XX (정보) -> 요청을 받았으며 프로세스를 계속한다.
- 2XX(성공) -> 요청을 성공적으로 받았으며 인식했고 수용했다.
- 3XX(리다이렉션) -> 요청을 완료하기 위해 추가 작업 조치가 필요하다.
- 4XX(클라이언트 오류) -> 요청의 문법이 잘못되었거나 요청을 처리할 수 없다.
- 5XX(서버 오류) -> 서버가 명백히 유효한 요청에 대해 충족에 실패했다.
Httpie
- 요청을 Command Line으로 동작하는 파이썬 기반 프로그램 (=http client)
- 다른 http Client 보다 가볍고 설치하기 편하기 떄문에 사용
-httpie 설치
>>pip install --upgrade httpie
-httpie 명령어
>>http [flags] [METHOD] URL [ITEM[ITEM]]
▪flags : 옵션
▪ METHOD : HTTP METHOD
▪ URL : 요청이나 응답의 대상 URL
▪ ITEM : 처리할 값 (인자)
▪ POST / PUT : =로 표현
▪ GET : ==로 표현
▪ Httpie 명령어 사용 예시
▪ GET
http(GET) 대상주소 인자 ==값
http (GET) example.org a==1 b==2
http example.org a==1 b==2
▪ PUT
http(PUT) 대상주소 GET인자 ==값 PUT인자=값
http PUT example.com a==1 b==2
▪ Get 인자가 있으면 쓰고 없으면 안쓴다. ▪ Put 인자가 있으면 쓰고 없으면 안쓴다.
2. CBV
-장고의 view
- 호출 가능한 객체(callable object) 로 정의
-> 함수 / 클래스
- 함수와 클래스의 차이 : 함수 (상속x) / 클래스 (상속o)
- 상속을 사용하는 이유는 ? 중복의 제거 / 코드의 재사용
따라서 CBV를 사용하는 이유는 상속을 사용해 코드를 더 간단하게 작성하기 위해 사용
-FBV(Function Based View) : 함수 기반 뷰
##실습하면서 익혀봅시다
순서 : 프로젝트 생성 -> 앱 생성 -> 템플릿 추가
가상환경 생성 및 활성화
$python -m venv myvenv
$ source myvenv/Scripts/activate
프로젝트 생성
$ django-admin startproject CBV
$ cd CBV
앱 생성
$python manage.py startapp classBaseCrud
settings.py 에 앱 추가
INSTALLED_APPS = [
'classBaseCrud',
]
models.py 작성하기
- 클래스 생성
from django.db import models
# 클래스를 생성하여 제목, 생성일, 수정일, 본문 필드 작성
class ClassBlog(models.Model):
title = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
#auto_now_add 옵션 : model이 최초 저장시에만 현재 날짜 적용
updated_at = models.DateTimeField(auto_now=True)
#auto_now 옵션 : 데이터가 저장 될 때마다 현재 날짜로 갱신
body = models.TextField()
def __str__(self):
return self.title
-admin.py에 생성한 클래스 등록
from django.contrib import admin
from .models import ClassBlog
admin.site.register(ClassBlog)
-마이그레이션
$ python manage.py makemigrations
$ python manage.py migrate
views.py 작성하기
1) 사용할 모듈 추가 - CRUD
게시글 목록 | ListView |
새로운 게시글 생성 | CreateView |
게시글 상세 내용 | DetailView |
게시글 수정 | UpdateView |
게시글 삭제 | DeleteView |
-Generic Views : 웹 개발 시 자주 사용하는 기능을 장고에서 미리 제공 / 외부 모듈 적용이 필요하다
#사용할 모듈 추가 CRUD
from django.utils import timezone
from django.urls import reverse_lazy
from django.views.generic.list import ListView
#게시글 목록 보여줌
from django.views.generic.detail import DetailView
#게시글의 상세 내용을 보여줌
from django.views.generic.edit import CreateView, UpdateView, DeleteView
#게시글 생성, 수정, 삭제
from .models import ClassBlog
2)모듈을 상속해 클래스 작성(classBaseCrud/views.py)
-CREATE
#CREATE
class BlogCreate(CreateView):
model = ClassBlog
fields = ["title", "body"]
success_url = reverse_lazy('list')
#reverse_lazy
#- redirect 와 같은 기능으로 , generic view에서 주로 사용
#- reverse_lazy() 함수 사용 인자로 URL 이름을 넣어줌
#- 작업이 성공적으로 완료되었을 경우 해당 URL로 이동
-READ
#READ
class BlogView(ListView):
model = ClassBlog
template_name = 'classBaseCrud/list.html'
context_object_name = 'blog_list'
# List Views
#- Generi view 중 특정 모델의 리스트를 출력해주는 뷰
#- 모델에 대한 쿼리가 필요하고(queryset)
#- 어느 템플릿에 (template_name)
#- 어떤 파라미터명으로 전달할지 (context_object_name) 를 정의
#- 약속되어있는 html 이름을 사용하지 않고 작성하기 위함
#- 해당 html을 사용할 class에 template_name을 설정하면 된다
#context_object_name : 임의로 설정하여 기본적으로 설정되어있는 객체를 가져옴
class BlogRead(DetailView):
context_object_name = 'blog'
model = ClassBlog
#DetailView
#- 특정 모델의 특정 오브젝트에 대한 자세한 정보를 출력해주는 뷰
#- 어떤 모델의 어떤 오브젝으를 어떤 템플릿에 전달할지 정의
-UPDATE
#UPDATE
class BlogUpdate(UpdateView):
model = ClassBlog
fields = ["title", "body"]
success_url = reverse_lazy("list")
-DELETE
#DELETE
class BlogDelete(DeleteView):
model = ClassBlog
success_url = reverse_lazy("list")
앱 내부에 urls.py 생성 및 작성
- 작성할 클래스에 맞는 url path 작성
- (urls.py / classBaseCurd)
from django.urls import path
from .import views
#작성할 클래스에 맞는 url path 작성
urlpatterns = [
path("", views.BlogView.as_view(), name='list'),
#as_view : view를 하나 만들어서 이를 return
#함수가 하나 만들어지는 것과 같음
#클래스를 정의한 후 이에 해당하는 함수 만들어 사용하는 방식
path("create/", views.BlogCreate.as_view(), name="create"),
path("read/<int:pk>/", views.BlogRead.as_view(), name="read"),
path("update/<int:pk>/", views.BlogUpdate.as_view(), name="update"),
path("delete/<int:pk>/", views.BlogDelete.as_view(), name="delete"),
]
프로젝트 urls.py 에 앱 urls.py 추가
- (urls.py / CBV)
from django.contrib import admin
from django.urls import path, include
#django.urls 의 include 모듈 추가
#앱의 urls.py 파일을 프로젝트 urls.py에 추가
import classBaseCrud.urls
import classBaseCrud.views
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(classBaseCrud.urls)),
]
templates 생성하기
- 수행 결과를 보여주는 HTML 템플릿이 존재해야하고
ListView 는 블로그 리스트 HTML / CreateView, UpdateView 는 입력공간(form)을 갖는 HTML
DetailView는 상세 페이지 HTML / DeleteView 는 삭제 작업을 확인하는 HTML 필요
- Generic View 에서는 기본적으로 설정된 이름이 존재
- 다른 이름으로 HTML 을 작성하기 위해서는 추가 설정이 필요
View 이름 | HTML 이름 |
ListView | (소문자 모델)_list.html |
CreateView | (소문자 모델)_form.html |
DetailView | (소문자 모델)_detail.html |
UpdateView | (소문자 모델)_form.html |
DeleteView | (소문자 모델)_confirm_delete.html |
##template폴더 구성할 때 template 안에 HTML 파일을 작성하는 게 아니라 App 이름의 폴더를 작성하고 그 안에 작성
#classblog_list.html
<!DOCTYPE html>
<html lang="ko" dir="ltr">
<head>
<meta charset="utf-8">
<title>Class Base View</title>
</head>
<body>
<a href="{% url 'create' %}"> 추가 </a>
<br>
{% for blog in blog_list %}
<h2> {{ blog.title }} </h2>
<h2> {{ blog.created_at }} </h2>
<p> {{ blog.body }} </p>
<a href="{% url 'read' blog.id %}"> 자세히보기 </a><br>
<a href="{% url 'update' blog.id %}"> 수정 </a><br>
<a href="{% url 'delete' blog.id %}"> 삭제 </a><br>
{% endfor %}
</body>
</html>
#classblog_form.html
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="추가하기">
</form>
//HTTP POST, PUT, DELETE 🡪 {% csrf token %} 사용
//{{ form.as_p}} : view에서 전달한 form 객체를 템플릿 변수로 사용 / 폼의 각 필드를 p태그 안에 배치
#classblog_detail.html
<h1> 본문 자세히 보기 페이지 </h1>
<hr>
<h2> 제목 : {{ blog.title }} </h2>
<h4> 날짜 : {{ blog.created_at }} </h4>
본문 : {{ blog.body }}
#classblog_confirm_delete.html
<form method="POST">
{% csrf_token %}
<h2>진짜 지울거야?</h2>
<br>
<br>
<input type="submit" value="삭제">
</form>
##결과
'Web > Django' 카테고리의 다른 글
[Django_심화]3 - viewset & router (2) | 2019.11.03 |
---|---|
[Django_심화]2 - Rest, Serializer (0) | 2019.11.03 |
[6주차]Form (0) | 2019.03.06 |
[5.5주차]Faker (0) | 2019.03.05 |
[5주차]2.Pagination (0) | 2019.03.05 |