DRF ๊ตฌํ˜„


๐Ÿ’ก Django ๊ธฐ๋ณธ ๊ตฌํ˜„ vs DRF ๊ตฌํ˜„

์˜ค๋Š˜์€ Django ๊ธฐ๋ณธ๊ตฌํ˜„๊ณผ DRF๊ตฌํ˜„์˜ ์ฐจ์ด์ ์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ–ˆ๋‹ค.

์ฒ˜์Œ์— instagram์—์„œ Post๋ชจ๋ธ์— ๋Œ€ํ•œ API๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์ด ํ–ˆ์—ˆ๋‹ค.

๏ผ‘. ์ƒˆ ํฌ์ŠคํŒ… ๋‚ด์šฉ์„ ๋ฐ›์•„ ๋“ฑ๋กํ•˜๊ณ ,ํ™•์ธ โ‡จ /post/new/ ; POST์š”์ฒญ

๏ผ’. ํฌ์ŠคํŒ… ๋ชฉ๋ก ๋ฐ ๊ฒ€์ƒ‰ ์‘๋‹ต โ‡จ /post/ ; GET์š”์ฒญ

๏ผ“. 1๋ฒˆ ํฌ์ŠคํŒ… ๋‚ด์šฉ ์‘๋‹ต โ‡จ /post/1/ ; GET์š”์ฒญ

๏ผ”. 1๋ฒˆ ํฌ์ŠคํŒ… ๋‚ด์šฉ ๊ฐฑ์‹ ํ•˜๊ณ , ํ™•์ธ ์‘๋‹ต โ‡จ /post/1/update ; POST์š”์ฒญ

๏ผ•. 1๋ฒˆ ํฌ์ŠคํŒ… ๋‚ด์šฉ ์‚ญ์„ธํ•˜๊ณ , ํ™•์ธ ์‘๋‹ต โ‡จ /post/1/delete ; POST์š”์ฒญ


REST API ์Šคํƒ€์ผ๋กœ ์žฌ์„ค๊ณ„๋ฅผ ํ•ด๋ณธ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

๏ผ‘. /post/์ฃผ์†Œ

  • GET ๋ฐฉ์‹ ์š”์ฒญ : ๋ชฉ๋ก ์‘๋‹ต

  • POST ๋ฐฉ์‹ ์š”์ฒญ : ์ƒˆ ๊ธ€์„ ์ƒ์„ฑํ•˜๊ณ  , ํ™•์ธ ์‘๋‹ต


๏ผ’. /post/10/์ฃผ์†Œ

  • GET ๋ฐฉ์‹ ์š”์ฒญ : 10๋ฒˆ ๊ธ€ ๋‚ด์šฉ ์‘๋‹ต

  • PUT ๋ฐฉ์‹ ์š”์ฒญ : 10๋ฒˆ ๊ธ€ ๋‚ด์šฉ ์ˆ˜์ •/์ €์žฅ, ํ™•์ธ ์‘๋‹ต

  • DELETE ๋ฐฉ์‹ ์š”์ฒญ : 10๋ฒˆ ๊ธ€ ์‚ญ์ œ, ํ™•์ธ ์‘๋‹ต


# models.py
class Post(models.Model):
    message = models.TextField()

# froms.py
class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = '__all__'

# views.py
def post_list(request):
    if request.method == "POST":
        # ์ƒˆ ๊ธ€ ์ €์žฅ์„ ์œ„ํ•œ ๊ตฌํ˜„
        form = PostForm(request.POST, request.FILES)
        if form.is_valid:
            post = form.save()
            return JsonResponse(post)
        else:
            return JsonResponse(form.errors)
    else:
        # ๋ชฉ๋ก ์‘๋‹ต์„ ์œ„ํ•œ ๊ตฌํ˜„(GET)
        return JsonResponse(Post.objects.all())

def post_detail(request):
    post_detail = Post.get_object_or_404(Post,pk=pk)
    if request.method == "PUT":
        # ํŠน์ • ๊ธ€ ๊ฐฑ์‹ ์„ ๊ตฌํ˜„
        put_data = Querydict(request.body)
        form = PostForm(put_data, instance=post)
        if form.is_valid:
            post = form.save()
            return JsonResponse(post)
        else:
            return JsonResponse(form.errors)
    elif request.method == "DELETE":
        # ํŠน์ • ๊ธ€ ์‚ญ์ œ๋ฅผ ๊ตฌํ˜„
        post.delete()
        return HttpResponse()
    else:
        # ํŠน์ • ๊ธ€ ๋‚ด์šฉ ์‘๋‹ต์„ ๊ตฌํ˜„ 
        return JsonResponse(post)

์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ ๋ชจ๋ธ์— ๋Œ€ํ•ด์„œ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด,

Model/Form์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๊ฑฐ์˜ ์ •ํ˜•ํ™”๋œ ํŒจํ„ด์„ ๋ณด์—ฌ์ค€๋‹ค.

DRF๋Š” ์ด๋Ÿฐ ์ •ํ˜•ํ™”๋œ ์ค‘๋ณต์„ ์ค„์ผ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” CBV๋ฅผ ๋น„๋กฏํ•˜์—ฌ

๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ด์ค€๋‹ค.

์œ„์˜ ์ฝ”๋“œ๋ฅผ DRF๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๊ธฐ ์ „์— djangorestframework ์„ค์น˜๋ฅผ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

pip install djangorestframework

์„ค์น˜๋ฅผ ์™„๋ฃŒ ํ–ˆ์œผ๋ฉด settings.INSTALLED_APPS์— rest_framework๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  urlpatterns์— ๋‹ค์Œ ํŒจํ„ด์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

# ํ”„๋กœ์ ํŠธ๋ช…/urls.py
urlpatterns = [
    path('api-auth', include('rest_framework.urls')
]

์—ฌ๊ธฐ์„œ include ์•ˆ์— ์žˆ๋Š” rest_framework๋Š” ๋‹จ์ˆœํžˆ django.contrib.auth์˜

login, logout์„ ํ™œ์šฉํ•œ ๊ฒƒ์ด๋‹ค.

from django.conf.urls import url 
from django.contrib.auth import views

app_name = 'rest_framework' 

urlpatterns = [
    url(r'^login/$', views.LoginView.as_view(template_name='rest_framework/login.html'), name='login'),
    url(r'^logout/$', views.LogoutView.as_view(), name='logout'),
]

์ด์ œ DRF๋กœ Post๋ชจ๋ธ์— ๋Œ€ํ•œ API๋ฅผ ์„ค๊ณ„ํ•ด๋ณด๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ๋‹ค.

# models.py
class Post(models.Model):
    message = models.TextField()


# serializers.py
from rest_framework import serializers
from .models import Post

class PostSerializer(ModelSerializer):
    class Meta:
        model = Post
        fields = '__all__'


# views.py
from rest_framework import viewsets
from .seliarlizer import PostSerializer

class PostViewSet(ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer


# urls.py
from rest_framework.routers import DefaultRouter
from . import views

router = DefaultRouter()

# 2๊ฐœ์˜ URL์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค.
# ์ƒ์„ฑ๋œ "2๊ฐœ์˜ URL"์€  router.urls์— listํ˜•ํƒœ๋กœ ์กด์žฌํ•œ๋‹ค. 
router.register('posts', views.PostViewSet)

urlaptterns = [
    path('', include(routers.urls)),
]

๊ต‰์žฅํžˆ ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์กŒ๋‹ค.

Form/ModelForm โ†’ Serializer/ModelSerializer

FBV/CBV โ†’ FBV/CBV ๊ทธ๋ฆฌ๊ณ  ViewSet/ModelViewSet ๋“ฑ


๊ทธ๋ฆฌ๊ณ  ursl.py ๋ถ€๋ถ„์ด ์ดํ•ด๊ฐ€ ์ž˜ ์•ˆ๋˜์„œ

router.urls๋ฅผ ์ถœ๋ ฅํ•ด ๋ดค๋”๋‹ˆ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™์•˜๋‹ค.

[
    <URLPattern '^post/$' [name='post-list']>, 
    <URLPattern '^post\.(?P<format>[a-z0-9]+)/?$' [name='post-list']>,

    <URLPattern '^post/(?P<pk>[^/.]+)/$' [name='post-detail']>,
    <URLPattern '^post/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='post-detail']>,

    <URLPattern '^$' [name='api-root']>,
    <URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>
]



๐Ÿ“š References