Django Postman을 이용한 간단한 API 요청

Gom La·2023년 4월 5일
0

장고와 친해지기

목록 보기
7/17
post-thumbnail

📌 복습!!
Django는 브라우저에서 클라이언트(사용자)요청 을 보내면, 해당 요청 주소 와 일치하는 기능(view) 을 파악하여 기능을 수행 하고 요청에 맞는 응답 을 주는 흐름을 가지고 있다.

일반적이 화면의 이동만 하는 요청의 경우에는 요청 주소에 특정한 값을 전달할 필요가 없다.

하지만 데이터 생성, 수정, 삭제 등과 같이 특정 기능을 필요로 하는 요청을 보내면 기능을 수행하기위한 파라미터(변수) 가 필요하다.

이를 클라이언트(사용자)가 전달해 줄 수 있는데 그 파라미터(변수)를 전달하는 방법을 알아보려고 한다.

🔖 파라미터 전달

# 📌 urls.py
urlpatterns = [
    path('', index_view, name='index'),
]

# 📌 views.py
def index_view(request):
    user = Users.objects.filter(username='admin').first()
    email = user.email if user else "Anonymous User!"
    
    return render(request, "index.html", {"welcome_msg" : f"Hello {email}!", "hello" : "World"})

위 함수는 주소 창에 아래의 주소로 함수가 처리하여 index.html페이지로 이동을 한다.

http://127.0.0.1:8000/shortener/

하지만 이때 우리는 url 주소만 입력했지 특정 값 이나 파라미터(요소) 등을 전달한 적이 없다.

이제 파라미터가 포함한 요청을 보내 함수가 어떻게 파라미터를 받을 수 있는지 살펴보자.

➤ path 파라미터

첫 번째로 값을 전달하는 방법에는 path 파라미터가 있다.

path 파라미터란? 요청 url 주소에 포함된 하나의 변수 이다.

http://127.0.0.1:8000/shortener/user/1 GET

위의 요청 주소에는 HTTP GET method로 user의 값이 1 인 데이터를 요청함 과 같은 의미를 가진다.

이러한 path 파라미터는 아래와 같은 특징을 가지는데

특징

  • 주소에서 포함된 변수를 담는다.
  • path 파라미터는 엔드포인트의 일부이다.
  • 원하는 조건의 데이터들 혹은 하나의 데이터에 대한 정보를 받아올때 적절하다.

이제 Django에서 path 파라미터가 담긴 url을 어떻게 작성하면 좋을까?

📌 urls.py

urlpatterns = [
	# 파라미터 미포함
    path('shortener', index_view, name='index'),
    
	# path 파라미터가 포함
    # shortener/user/1/
	path('user/<int:user_id>', get_user),
]

전달하려는 파라미터가 없다면 위와 같이, 반대로 전달하려는 파라미터를 주소에 담고 싶다면 아래와 같이 사용하면 된다.

/shortener/user/1/에서 1<int:user_id>가 부분이다.

🗣 int형 데이터를 user_id 변수에 담아 보내라!!

라고 생각하면 되겠다.

이렇게 작성한 url 주소의 path 파라미터를 view의 함수가 어떻게 받을까?

# 📌 urls.py
urlpatterns = [
	path('user/<int:user_id>', get_user),
]

# 📌 views.py
def get_user(request, user_id):
    	...
        
        user = Users.objects.filter(pk=user_id).first()
        
        ...
        return render(request, "base.html", {"user" : user,  "params" : [abc, xyz]})

url 주소를 user/<int:user_id>user_id라는 파라미터를 보냈다.

그렇다면 해당하는 url 주소를 받는 함수 get_user()는 파라미터로 동일한 user_id를 받아야만한다.

그래서 함수 get_user()함수에 requestuser_id를 파라미터로 받아 코드를 작성했다.

이렇게 받은 user_id는 하나의 변수로 사용이 되면 ORM을 통해 데이터를 조회하거나 데이터 처리 등에 사용이 된다.(CRUD)


➤ query string(파라미터)

요청 주소에 파라미터를 담는 방법이 하나 더 존재한다.

이 방법은 query string이라 부르며 query 파라미터라고도 한다.

http://127.0.0.1:8000/shortener/user/1?abc=ABC&xyz=XYZ GET

위의 요청 주소에는 path 파라미터인 HTTP GET method로 user의 값이 1 인 데이터를 요청함의 의미와 추가적인 abc값이 ABC이며 xyz값이 XYZ이다.라는 조건이 추가가 되었다.

이것을 바로 query string이라 부르는데 아래와 같은 특징을 가진다.

특징

  • 엔드포인트에서 물음표(?) 뒤에 등장하며, 변수를 담는다.
    shortener/user/1?abc=ABC&xyz=XYZ
  • key=value로 이루어져 있고 &으로 연결할 수 있다.
  • 조건을 줘서 정제된 결과물을 얻을 수 있다.
  • filtering, sorting, searching에 적절하다.

그럼 Django에서 query string 담긴 url을 어떻게 작성하면 좋을까?
query string은 path 파라미터와 다르게 url에서는 특별히 작성하지 않는다.

query string은 middle ware가 넘겨주는 request에 담겨 넘어오기 때문이다.


query string을 view의 함수가 어떻게 받을까?

def get_user(request, user_id):
    ...
        abc = request.GET.get("abc")
        xyz = request.GET.get("xyz")
        user = Users.objects.filter(pk=user_id).first()
        return render(request, "base.html", {"user" : user,  "params" : [abc, xyz]})

위에서 query string은 request변수에 담겨 온다고 했다.

view에서 함수는 urls.py를 거쳐 views.py로 넘어 올때 몇개의 middle ware를 거치는데, 이때 request변수에 query string의 변수와 값도 함께 넘어 온다.

view의 함수는 반드시 request를 파라미터로 받아야 하기 때문에 query string으로 넘어온 값을 사용할 수 있다.

request.GET.get("abc")로 abc 키값을 가진 query string을 받았다.

🗣 이는 request의 GET(HTTP method)안에 "abc"값을 가져와!

라는 뜻으로 생각하면 된다.


🔖 context객체를 template에 렌더하는 방법

📌 views.py

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def get_user(request, user_id):
    ...
        abc = request.GET.get("abc")
        xyz = request.GET.get("xyz")
        user = Users.objects.filter(pk=user_id).first()
        return render(request, "base.html", {"user" : user,  "params" : [abc, xyz]})

위와 같이 path 파라미터를 이용해 Users객체와 query string을 이용해 abc, xyz값을 render()함수의 context에 전달하였다.

이렇게 전달한 context를 어떻게 html문서에서 이용할 수 있을까 알아보자.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Base Page</title>
</head>
<body>
    {{ user }} <br>
    {{ user.email }}<br>
    {% for i in params %}
        {{ i }}<br>
    {% endfor %}
    {% if user.email == "admin@shortener.com" %}
        <h1>{{ user }}는 할 수 있다.</h1>
        {% else %}
        <h1>{{ user }}는 할 수 없다.</h1>
    {% endif%}
</body>
</html>
  1. Django 템플릿 문법
    {{ user }}, {{ user.email }}과 같이 템플릿 변수로 또는 {% for i in params %}와 같은 템플릿 태그를 이용하여 python문법을 html문서에서 사용할 수 있다.
  2. user, user.email
    view에서 user라는 객체를 통체로 보냈기 때문에 user객체 안에 있는 email도 사용이 가능하다.
  3. 그외 템플릿 필터도 존재하지만 자세한 내용은 다음에 다루도록 하겠다.

🔖 간단한 POSTMAN 사용

현재까지는 url요청을 브라우저의 주소창에 url 주소를 입력하여 요청을 보내는 방식을 사용하였다.

웹 개발을 하면서 브라우저를 열어 url을 입력하는 것도 방법이긴 하지만, Backend 개발자에게 브라우저를 열고 이벤트 UI/UX를 클릭하고 클릭한 요청을 기다리는 것이 오래걸리고 매번 그 과정을 반복하는 것은 번거롭다.

그래서 브라우저의 변화는 보지 않고 요청을 보내면 결과 값만을 확인할 수 있는 POSTMAN을 사용해 보려고 한다.

POSTMAN 은 API 개발 방식에 사용되며, API개발자에게 필수적인 프로그램이다.

📌 views.py

@csrf_exempt  # csrf 예외 처리
def get_user(request, user_id):
    if request.method == 'GET':
        abc = request.GET.get("abc")
        xyz = request.GET.get("xyz")
        user = Users.objects.filter(pk=user_id).first()
        return render(request, "base.html", {"user" : user,  "params" : [abc, xyz]})
    
    elif request.method == 'POST':
        username = request.GET.get("username")
        if username:
            user = Users.objects.filter(pk=user_id).update(username=username)

        return JsonResponse(status=201,data=dict(msg="You just reached with Post Method!"), safe=False)

위의 코드에 HTTP mehtod를 if문을 통해 분기를 걸었다.

HTTP method가 뭔데?
HTTP method는 API 요청(브라우저의 url요청, 이벤트 버튼의 api 등)에서 요청 방식을 정하는 변수이다.

HTTP method는 GET, POST, DELETE, FETCH 등이 존재하며 자세한 내용은 다른 글에서 상세히 알아보고, 코드로 작성한 GET, POST만 다뤄보려고 한다.

request.method == 'GET'
일반적으로 브라우저 주소창에 입력해 화면이동하는 것은 HTTP method가 GET에 해당한다.

request.method == 'POST'
일반적인 사이트에서 버튼을 클릭하여 저장처리를 하는 요청이 HTTP method가 POST에 해당한다.


그래서 왜 나눈건데?
코드에서 GET과 POST를 나눈 이유는 view에서 HTTP method가 무엇이냐에 따라 어떻게 처리를 하는지 그리고 어떤 처리에 HTTP method를 설명하려고 한다.

request.method == 'GET'에는 abc, xyz, user를 context에 담아 화면이동이 구현되어 있다.

		abc = request.GET.get("abc")
        xyz = request.GET.get("xyz")
        user = Users.objects.filter(pk=user_id).first()
        return render(request, "base.html", {"user" : user,  "params" : [abc, xyz]})

request.method == 'POST'에는 query string 'username'을 받아 user객체의 username값을 변경하는 로직이 구현되어 있다.

    elif request.method == 'POST':
            username = request.GET.get("username")
            if username:
                user = Users.objects.filter(pk=user_id).update(username=username)

            return JsonResponse(status=201,data=dict(msg="You just reached with Post Method!"), safe=False)

먼저 브라우저에서 주소창에 url을 입력하면 GET 방식의 화면이동이기 때문에 화면이 이동하며 html에 아래와 같이 나오는 것을 볼 수 있다.

하지만 POST 방식은 저장을 버튼이나 특정 이벤트를 화면에서 구현하지 않는 이상 바로 확인이 불가능 하다.

그래서 우리는 POSTMAN 을 사용하는 것이다.

  • POSTMAN을 이용하여 브라우저 주소를 입력하듯 api주소 입력칸에 url을 입력하고
  • 왼쪽 편에 있는 HTTP method를 POST로 변경해 준다.
  • POST요청 코드에서 username의 query string을 받아 Users의 username값을 변경하고 있기 때문에 파라미터에 username의 값을 추가하자.
  • 우측 편에 SEND 버튼을 클릭하면 API를 전송이 된다.
  • 우리가 입력한 "msg"의 값을 확인 할수 있으면 성공한 것이다.

이렇게 요청을 성공한 후 다시 브라우저에서 동일한 주소를 입력하여 화면을 확인해 보자.

username이 변한 결과를 확인할 수 있을 것이다.

profile
인생 개발자 라곰!!

0개의 댓글