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']>
]