Django RESTful Framework

MVT๋ž€?

Model: ๋ฐ์ดํ„ฐ ๊ตฌ์กฐํ™”

View: ๋ฐ์ดํ„ฐ๊ฐ€ ํ˜๋Ÿฌ๋‹ค๋‹ˆ๋Š” ๊ณณ

Template: ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ณณ

API ๋ž€?

  • Application Programming Interface

    • ๊ฐœ๋ฐœ์ž์šฉ ์ ‘์ 

      • ๊ฐœ๋ฐœ์ž๋Š” Data๋งŒ ํ•„์š”ํ•จ!

Request

: ์š”์ฒญ์€ URL๋กœ ๋ณด๋‚ธ๋‹ค!

Data์˜ ํ‘œ๊ธฐ๋ฒ•

: ์•ฝ์†

  • JSON

    • JavaScript Object Notation

    • Javascript ๊ฐ์ฒด์‹ ํ‘œ๊ธฐ๋ฒ•

  • XML

    • eXtended Markup Language (W3C, 1996)

Why not HTML?

: key๊ฐ’์ด ๋ฐ˜์˜์ด ์•ˆ ๋จ!

  • ๊ทธ๋ž˜์„œ ๋“ฑ์žฅํ•œ ๊ฒƒ์ด tag๋ฅผ ๋‚ด๋ง˜๋Œ€๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” XML

Why JSON

  • XML์ด ๋‹ซ๋Š” tag ๋•Œ๋ฌธ์— ๊ธธ์ด๊ฐ€ ๊ธธ๋‹ค

    • ๋ˆ

์šฐ๋ฆฌ๊ฐ€ ํ•  ์ผ

: Django ์—์„œ JSON ํ˜•์‹์— ๋งž์ถฐ์„œ Data๋งŒ ์ œ๊ณตํ•œ๋‹ค!

JSON ... ๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ๋Š”?

image-20200511121142258

Javscript & framewokr๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ์ด์œ 

  1. ์ข‹์€ ์œ ์ € ๊ฒฝํ—˜์„ ์œ„ํ•ด์„œ

    • UX ์•ˆ ์ข‹์œผ๋ฉด -> User X -> ๋ˆ X

    • data -> ์ธ๊ฐ„์ด ๋ญ˜ ์ข‹์•„ํ• ๊นŒ?

    • ๋ชจ๋ฐ”์ผ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ (์›น)

    • churn (์ดํƒˆ์œจ)

    • JS ํ•„์ˆ˜ (Adobe Flash)

  2. ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์ด ํŽธํ•ด์„œ

Django ๋‹ค์‹œ ๊น”๊ธฐ

pip uninstall django

pip install django==2.1.15

Faker ์‚ฌ์šฉํ•˜๊ธฐ

faker ์„ค์น˜

pip install faker

Dummy data ๋งŒ๋“ค๊ธฐ

In [1]: from faker import Faker                                                                                     

In [2]: f = Faker()                                                                                                 

In [3]: f.text()                                                                                                    
Out[3]: 'Soldier live various argue many expect important once. Next possible whom I.\nSome national left wall score few else always. Action less culture spring any night.'

In [4]: f.name()                                                                                                    
Out[4]: 'Jenna Davis'

In [5]: f.paragraph()                                                                                               
Out[5]: 'Improve knowledge hot matter himself. Growth water act bill to can discuss there. Follow out person vote action someone.'

In [6]: f.paragraph(4)                                                                                              
Out[6]: 'Early program four bill. Comput

RESTful API

https://meetup.toast.com/posts/92 ์ฐธ๊ณ ํ•˜๊ธฐ

: url์„ ๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๋Š” ๋ฐฉ์‹ (๊ณตํ†ต์˜ rule / ์•ฝ์†)

RESTful

  1. HTTP verb (GET, POST)

  2. ๋ช…์‚ฌ (๋ณต์ˆ˜ํ˜•)๋กœ ๊ตฌ์ •

๊ทœ์น™๋“ค

  • ๋™์‚ฌ URL์— ์ง‘์–ด ๋„ฃ์ง€๋งˆ! -> HTTP method ํ™œ์šฉํ•ด

    • C (POST)

      • (POST) / articles /

    • R (GET)

      • index (๋ชจ๋“  ์ •๋ณด) - (GET) / articles /

      • detail (ํ•˜๋‚˜์˜ ์ •๋ณด) - (GET) / articles / <id>

    • U (PUT/PATCH)

      • (PUT) / articles / <id>

    • D (DELETE)

      • (DELETE) / articles / <id>

  • ๋ชฉ์ ์–ด๋งŒ URL์— ์ง‘์–ด ๋„ฃ์–ด -> ๋ณต์ˆ˜ํ˜•์œผ๋กœ

    • Data

API ๊ด€๋ จ URL

  1. subdomain

    • ex)

      • lab.ssafy.com

      • api.gitbub.com

  2. ๋ถ„๋ฆฌ URL /api/

    • ssafy.com/api/lectures/

    • github.com/api/repos/

  3. versionning

    • ssafy.com/api/v1/lectures/

    • POST /api/articles/1/like/

    • POST /api/articles/1/comments/like/

Django REST Framework (DRF)

djangorestframework ์„ค์น˜

pip install djangorestframework

์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ

$ pip show djangorestframework
Name: djangorestframework
Version: 3.11.0
Summary: Web APIs for Django, made easy.
Home-page: https://www.django-rest-framework.org/
Author: Tom Christie
Author-email: tom@tomchristie.com
License: BSD
Location: /home/chloe/.local/lib/python3.6/site-packages
Requires: django
Required-by: drf-serializer-cache

Serialize (์ง๋ ฌํ™”)

ํฌ๋งท์˜ ๋ณ€ํ™˜ (๋ฐ์ดํ„ฐ๋ฅผ ์ „์†ก/์ด๋™)

dict -> JSON (stringify, serialize)

JSON -> dict (parse, deserialize)

์ง๋ ฌํ™”

: Object(์–ธ์–ด, database) -> String (JSON)

CREATE

image-20200511162710246

raise_exception์œผ๋กœ Error ์˜ˆ์˜๊ฒŒ ์ถœ๋ ฅํ•˜๊ธฐ

ex)

@api_view(['POST'])
def article_create(request):
    # ๊ธ€์„ ์ƒ์„ฑ
    serializer = ArticleSerializer(data=request.data)
    if serializer.is_valid(raise_exception=True):
        serializer.save()
    return Response(serializer.data)

ํ•˜๋‚˜๋งŒ ๋ณด๋ƒ„

image-20200511162920160

์—๋Ÿฌ๋ฉ”์‹œ์ง€

image-20200511162959467

yasg

  • API ๊ด€๋ จ ๋ฌธ์„œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑ

DRF yasg ์„ค์น˜ํ•˜๊ธฐ

https://drf-yasg.readthedocs.io/en/stable/readme.html

pip install drf-yasg

Dummy data JSON ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

fixtures ํด๋”์— dummy.json ๋„ฃ๊ธฐ

โ”œโ”€โ”€ api
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ settings.py
โ”‚   โ”œโ”€โ”€ urls.py
โ”‚   โ””โ”€โ”€ wsgi.py
โ”œโ”€โ”€ db.sqlite3
โ”œโ”€โ”€ manage.py
โ””โ”€โ”€ musics
    โ”œโ”€โ”€ admin.py
    โ”œโ”€โ”€ apps.py
    โ”œโ”€โ”€ fixtures
    โ”‚   โ””โ”€โ”€ dummy.json
    โ”œโ”€โ”€ __init__.py
    โ”œโ”€โ”€ migrations
    โ”œโ”€โ”€ models.py
    โ”œโ”€โ”€ serializers.py
    โ”œโ”€โ”€ tests.py
    โ”œโ”€โ”€ urls.py
    โ””โ”€โ”€ views.py

7 directories, 29 files

loaddata ๋กœ dummy.json ์„ DB์— ๋„ฃ๊ธฐ

$ python manage.py loaddata dummy.json
Installed 14 object(s) from 1 fixture(s)

dumpdata ๋กœ DB์— ์žˆ๋Š” data dumping ํ•˜๊ธฐ

$ python manage.py dumpdata musics
[{"model": "musics.artist", "pk": 1, "fields": {"name": "Coldplay"}}, {"model": "musics.artist", "pk": 2, "fields": {"name": "Maroon5"}}, {"model": "musics.music", "pk": 1, "fields": {"artist": 2, "title": "Girls Like You"}}, {"model": "musics.music", "pk": 2, "fields": {"artist": 2, "title": "Sunday Morning"}}, {"model": "musics.music", "pk": 3, "fields": {"artist": 1, "title": "viva la vida"}}, {"model": "musics.music", "pk": 4, "fields": {"artist": 1, "title": "paradise"}}, {"model": "musics.comment", "pk": 1, "fields": {"music": 1, "content": "\uac78\uc2a4 \ub77c\uc78c \uc720!!!"}}, {"model": "musics.comment", "pk": 2, "fields": {"music": 1, "content": "\ub9c8\ub8ec \ud30c\uc774\ube0c \uc9f1\uc9f1!"}}, {"model": "musics.comment", "pk": 3, "fields": {"music": 2, "content": "\uc77c\uc694\uc77c \ubaa8\ub2dd~~~"}}, {"model": "musics.comment", "pk": 4, "fields": {"music": 2, "content": "\ud558\uc9c0\ub9cc \ub0b4\uc77c\uc740 \uc6d4\uc694\uc77c"}}, {"model": "musics.comment", "pk": 5, "fields": {"music": 3, "content": "10\ub144\uc774 \uc9c0\ub098\ub3c4 \uc88b\uc544"}}, {"model": "musics.comment", "pk": 6, "fields": {"music": 3, "content": "\ub9c8\uce58 \ub0b4\uac00 \uc655\uc774 \ub41c \uac83 \uac19\uc544!"}}, {"model": "musics.comment", "pk": 7, "fields": {"music": 4, "content": "\ud30c\ub77c\ub2e4\uc774\uc2a4 \ud30c\ub77c\ud30c\ub77c\ud30c\ub77c\ub2e4\uc774\uc2a4~"}}, {"model": "musics.comment", "pk": 8, "fields": {"music": 4, "content": "\uc228\uaca8\uc9c4 \uba85\uace1!!!"}}]

dumpdata๋กœ dumping ํ•œ data๋ฅผ JSON file๋กœ ๋งŒ๋“ค๊ธฐ

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‹ค๋‹ฅ๋‹ค๋‹ฅ ๋ถ™์–ด์žˆ์Œ

python manage.py dumpdata musics > dump.json

indenting ์ค˜์„œ ์˜ˆ์˜๊ฒŒ ๋งŒ๋“ค๊ธฐ

--indent 2 -> indenting์„ 2 ์ค˜๋ผ

python manage.py dumpdata musics --indent 2 > dump2.json

result

[
{
  "model": "musics.artist",
  "pk": 1,
  "fields": {
    "name": "Coldplay"
  }
},
{
  "model": "musics.artist",
  "pk": 2,
  "fields": {
    "name": "Maroon5"
  }
},
{
  "model": "musics.music",
  "pk": 1,
  "fields": {
    "artist": 2,
    "title": "Girls Like You"
  }
},
{
  "model": "musics.music",
  "pk": 2,
  "fields": {
    "artist": 2,
    "title": "Sunday Morning"
  }
},
{
  "model": "musics.music",
  "pk": 3,
  "fields": {
    "artist": 1,
    "title": "viva la vida"
  }
},
{
  "model": "musics.music",
  "pk": 4,
  "fields": {
    "artist": 1,
    "title": "paradise"
  }
},
{
  "model": "musics.comment",
  "pk": 1,
  "fields": {
    "music": 1,
    "content": "\uac78\uc2a4 \ub77c\uc78c \uc720!!!"
  }
},
{
  "model": "musics.comment",
  "pk": 2,
  "fields": {
    "music": 1,
    "content": "\ub9c8\ub8ec \ud30c\uc774\ube0c \uc9f1\uc9f1!"
  }
},
{
  "model": "musics.comment",
  "pk": 3,
  "fields": {
    "music": 2,
    "content": "\uc77c\uc694\uc77c \ubaa8\ub2dd~~~"
  }
},
{
  "model": "musics.comment",
  "pk": 4,
  "fields": {
    "music": 2,
    "content": "\ud558\uc9c0\ub9cc \ub0b4\uc77c\uc740 \uc6d4\uc694\uc77c"
  }
},
{
  "model": "musics.comment",
  "pk": 5,
  "fields": {
    "music": 3,
    "content": "10\ub144\uc774 \uc9c0\ub098\ub3c4 \uc88b\uc544"
  }
},
{
  "model": "musics.comment",
  "pk": 6,
  "fields": {
    "music": 3,
    "content": "\ub9c8\uce58 \ub0b4\uac00 \uc655\uc774 \ub41c \uac83 \uac19\uc544!"
  }
},
{
  "model": "musics.comment",
  "pk": 7,
  "fields": {
    "music": 4,
    "content": "\ud30c\ub77c\ub2e4\uc774\uc2a4 \ud30c\ub77c\ud30c\ub77c\ud30c\ub77c\ub2e4\uc774\uc2a4~"
  }
},
{
  "model": "musics.comment",
  "pk": 8,
  "fields": {
    "music": 4,
    "content": "\uc228\uaca8\uc9c4 \uba85\uace1!!!"
  }
}
]

Last updated

Was this helpful?