Django(장고) url API 요청 및 응답

장현웅·2023년 9월 5일
0

이제 클라이언트의 API 요청(특정 url로 HTTP 메소드 요청)으로 데이터를 생성하는 것을 해볼 것이다.

API는 클라이언트가 어떤 요청을 보낼 수 있고 서버에서는 어떻게 응답해야 하는지를 통신하는 창구이자 일종의 계약이다. 클라이언트가 API 요청을 보낸다는 것은 웹 어플리케이션에서 서버로 그 계약을 수행할 것을 요청하는 것이라고 생각하면 된다. 서버는 이 요청에 따라 데이터를 제공하거나 작업을 수행한다.

API 요청을 보내는 과정은 다음과 같다.

1) 클라이언트가 API 엔드포인트(서버의 특정 URL)에 요청 메시지를 생성한다.

  • 엔드포인트 : 데이터를 주고 받는 장소. url기준으로 봤을 떄는 말 그대로 API에 요청하는 URL의 마지막 끝 포인트로 네트워크 관점에서는 데이터를 주고 받는 서버가 엔드포인트.
    • 클라이언트가 서버에게 요청 메시지를 보낼 때, 어떤 리소스나 기능을 대상으로 하는지 나타내기 위해 엔드포인트 URL을 지정한다.
    • GET http://127.0.0.1:8000/users : 사용자 정보를 요청하거나 생성하기 위한 URL
    • POST http://127.0.0.1:8000/todo/create/ : todo 게시물 생성을 위한 URL

2) 이 요청 메시지는 HTTP 메서드(GET, POST, PUT, DELETE 등)와 함께 엔드포인트URL로 전송된다.

  • HTTP 메서드
    • GET : 정보 조회. 서버에서 데이터를 읽는 역할
    • POST : 새로운 데이터 생성이나 수정
    • PUT: 리소스를 업데이트하기 위해 사용되며, 클라이언트가 리소스의 전체 내용을 제공한다.
    • DELETE: 리소스를 삭제하기 위해 사용된다.

3) 서버의 urls.py는 이 요청을 받아들이고 요청 URL 패턴을 어떤 View 함수와 연결되는지 정의한다.
4) views.py에서 정의된 URL 패턴과 연결된 View함수가 이 요청에 대한 응답 메시지를 생성하여 클라이언트에게 반환한다.

  • View 응답 유형
    - HttpResponse
    HttpResponse 클래스를 사용하여 HTML, JSON, 텍스트 응답을 생성
    - JsonResponse
    JsonResponse 클래스를 사용하여 JSON 형식의 응답을 생성
    - HttpResponseRedirect
    HttpResponseRedirect 클래스를 사용하여 리디렉션을 생성
    클라이언트를 다른 URL로 리디렉션하고자 할 때 사용
    ex) 회원가입 완료 후 로그인페이지로 이동하는 경우

url API 요청에 응답 생성해서 반환해보기 - ThunderClient


그럼 먼저 클라이언트의 url API 요청으로 todo 앱에 데이터를 생성해보기 위해서 클라이언트의 HTTP GET 요청에 응답이 제대로 반환되는지 확인해보자.

[App todo/views.py/getdata(request)]

from django.http import HttpResponse
from django.shortcuts import render


def todo(request):
    return render(request, 'todo_add.html')


def getdata(request):
    print(request.POST.get('added_todo1'))
    print(request.POST.get('added_todo2'))
    print(request.POST.get('added_todo3'))
    return HttpResponse('POST 완료!')

이 getdata함수의 경우는 클라이언트가 todo 페이지에서 서버로 input 요소들을 전달하면 HttpResponse 객체에 텍스트를 담아서 클라이언트에게 반환한다.

[App todo/views.py create(request)]

from django.http import HttpResponse
from django.shortcuts import render
from todo.models import Todo


def todo(request):
    return render(request, 'todo_add.html')


def getdata(request):
    print(request.POST.get('added_todo1'))
    print(request.POST.get('added_todo2'))
    print(request.POST.get('added_todo3'))
    return HttpResponse('POST 완료!')

def create(request): 
    return HttpResponse('GET 요청 확인!')

이 create 함수의 경우는 todo 페이지에서 클라이언트가 input 요소에 정보를 담아 서버로 보내면 views.py의 create 함수가 todo Model 클래스 틀에 담아서 데이터베이스에 데이터를 생성하고(넣고) 사용자에게 반환(나중에 HTML로 표현)도 할 것이기 때문에 todo앱의 models.py에서 Todo 클래스를 임포트해와야한다.

이제 todo 모델 데이터를 생성하는 함수를 정의했으니 urls.py에서 이 함수와 연결할 URL 패턴을 정의하자.

[App todo/urls.py]

from django.contrib import admin
from django.urls import path
from . import views


urlpatterns = [
    path('todo/', views.todo),
    path('getdata/', views.getdata),
    path('todo/create/', views.create),
]

todo 앱 안에 데이터를 만들 것이기 때문에 todo/의 하위경로에 create/을 지정하여 URL 패턴을 정의해준다.

이제 클라이언트의 요청이 서버에 잘 들어오고 서버의 응답이 잘 전달되는지 [ThunderClient]를 사용하여 확인해보자.


API 연결을 해봤으니 이제 todo Model 클래스 틀을 이용하여 실제 todo 데이터를 만들어서 데이터베이스에 넣어보자.

클라이언트 url API 요청으로 todo 모델 데이터 만들고 데이터베이스에 넣어보기


(Django - 데이터 모델 참고)

Django 모델을 사용하여 데이터베이스에 새로운 레코드(행, row)를 생성하는 메서드

from 앱.models import	# 앱의 데이터 모델 클래스

앱의 모델 클래스.object.create(데이터 모델 클래스 속성 = '')
  • 앱의 모델 클래스는 django의 models 모듈에서 Model클래스를 상속받는다.
  • object는 앱의 모델 클레스 안에 ORM을 이용해서 데이터베이스와 연결해주는 부분이다.

이제 위 코드로 todo 데이터를 생성하고 ThunderClient로 url API 요청을 보내서 데이터베이스에 저장되는지 데이터베이스와 admin 페이지에서 확인해보자.

[App todo/models.py]

from django.db import models


class Todo(models.Model):                               # Todo Model 클래스는 django models 모듈의 model 클래스를 상속
  content = models.TextField()
  created_at = models.DateTimeField(auto_now_add=True)  # 만들 때 알아서 시간 기록
  updated_at = models.DateTimeField(auto_now=True)      # 수정할 때 알아서 시간 기록
  is_done = models.BooleanField(default=False)

  def __str__(self):
    return self.content

[App todo/views.py]

from django.http import HttpResponse
from django.shortcuts import render
from todo.models import Todo


def todo(request):
    return render(request, 'todo_add.html')


def getdata(request):
    print(request.POST.get('added_todo1'))
    print(request.POST.get('added_todo2'))
    print(request.POST.get('added_todo3'))
    return HttpResponse('POST 완료!')

def create(request): 
    Todo.objects.create(content='todo 데이터 생성 완료!')

    return HttpResponse('GET 요청 확인!')


이제! 테스트는 끝났다.

내가 원하는 건, 'todo 데이터 생성 완료'가 디폴트 데이터로 저장되는 것이 아니라 클라이언트가 제공한 정보를 담아서 저장하고 싶다!

클라이언트가 서버로 보내는 데이터를 데이터베이스에 저장하는 과정에 대해서 알아보겠다. (탬플릿(HTML) form 태그 참고)

HTML 폼(form)을 통해 클라이언트가 제공하는 정보를 데이터베이스에 저장하는 과정

  1. 클라이언트는 다양한 input 요소들 (입력 필드들)에 데이터를 입력하고, 제출 버튼을 클릭
  2. 입력한 데이터는 HTTP POST 또는 HTTP GET 요청의 본문(body)에 포함되어 서버로 전송된다.
  3. 서버의 views.py에서 전송된 데이터를 처리한다. 이 데이터는 일반적으로 key와 value 쌍으로 구성되어 있으며, 각 입력 필드는 HTML 폼(form)의 <body></body>태그에서 지정한 'name'속성키(key)로 가지고, 클라이언트의 입력값을 해당 키의 값(value)로 데이터베이스에 전달된다.
  4. 데이터베이스가 서버에서 데이터를 받으면, View 함수의 로직에 따라 저장된다. 데이터베이스는 Django ORM을 사용하여 모델 데이터와 HTML 폼을 연결하여 상호작용하면서 데이터를 저장하거나 업데이트 할 수 있다.

위에서 데이터베이스에 저장한 데이터를 admin에 가져오는 것은 GET 요청 방식
데이터를 담아서 보내는 것은 POST 요청 방식

ThunderClient에서 입력 필드의 이름(key)와 입력값(value)를 임의로 정해서 실제 POST가 잘 되는지 확인해보자.

[App todo/views.py]

from django.http import HttpResponse
from django.shortcuts import render
from todo.models import Todo
from django.views.decorators.csrf import csrf_exempt	# 보안토큰 임포트

def todo(request):
    return render(request, 'todo_add.html')


def getdata(request):
    print(request.POST.get('added_todo1'))
    print(request.POST.get('added_todo2'))
    print(request.POST.get('added_todo3'))
    return HttpResponse('POST 완료!')

@csrf_exempt	# 원래는 브라우저에서 사용자의 입력값을 서버로 보낼 떄 Template(HTML)의 form 태그 안에서 해야하는 작업을 테스트용으로 views.py에서 하고 있기 때문에 보안 토큰을 임포트 해야 한다.
def create(request): 
    print(request.POST.get('name'))
    print(request.POST.get('add_todo'))
    
    # Todo.objects.create(content='todo 데이터 생성 완료!')

    return HttpResponse('GET 요청 확인!')

이제 실제 데이터베이스에 저장해보겠다.
[App todo/views.py]

from django.http import HttpResponse
from django.shortcuts import render
from todo.models import Todo
from django.views.decorators.csrf import csrf_exempt

def todo(request):
    return render(request, 'todo_add.html')


def getdata(request):
    print(request.POST.get('added_todo1'))
    print(request.POST.get('added_todo2'))
    print(request.POST.get('added_todo3'))
    return HttpResponse('POST 완료!')

@csrf_exempt
def create(request): 

    Todo.objects.create(content=request.POST["content"])

    return HttpResponse('GET 요청 확인!')


지금까지 API를 이용해서 데이터베이스에 저장까지 해봤다.
이제부터는 Template를 만들어서 웹사이트에서 todo를 등록할 수 있도록 만들어보겠다.

0개의 댓글