파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 강의를 듣고 정리한 글입니다.
/post/new/
주소로 POST 요청/post/
주소로 GET 요청/post/10/
주소로 GET 요청/post/10/update/
주소로 POST 요청/post/10/delete/
주소로 POST 요청/post/
주소
from django.db import models
class Post(models.Model):
message = models.TextField()
from django import froms
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
def post_list(request):
if request.method == 'POST':
# 새 글 저장을 구현
form = PostForm(request.POST, request.FILES)
if form.is_valid():
port = form.save()
return JsonResponse(post)
return JsonResponse(form.errors)
else:
# 목록 응답을 구현
return JsonResponse(Post.objects.all())
/post/10/
주소
/post/
주소와 마찬가지로 PUT, DELETE 요청을 동일 주소(view함수)에서 분기 처리한다.
컨셉 코드1과 마찬가지로 JsonResponse를 통해 모델 직렬화를 지원하지는 않는다. 따로 커스텀 해야한다.
def post_detail(request, pk):
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)
return JsonResponse(form.errors)
elif request.method == 'DELETE':
# 특정 글 삭제를 구현
post.delete()
return HttpResponse()
else:
# 특정 글 내용 응답을 구현
return JsonResponse(post)
→ 총 5개의 뷰 처리가 필요.
다른 모델에 대해서 동일한 기능을 구현한다면, Model/Form을 제외하고는 거의 정형화된 패턴이다.
→ DRF는 이런 정형화된 중복을 줄일 수 있도록 도와주는 Class Based View를 비롯하여 다양한 기능을 지원한다.
공식문서를 확인하고 설치하자. 공식문서에 익숙해지는것이 실력의 기반이 된다.
# pip
pip install djangorestframework~=3.11.0
# peotry
poetry add djangorestframework@3.11.0
# ...
INSTALLED_APPS = [
'rest_framework',
# ...
]
urlpatterns = [
# ...
path('api-auth/', include('rest_framework.urls'))
]
단순히 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'),
]
위 컨셉코드에서는 /posts/
, /posts/10/
의 URL을 대응하기 위해 view를 두개 작성해서 각 2, 3개의 분기처리를 하였다.
하지만 DRF에서의 ViewSet을 활용하면, 하나의 ViewSet으로 두 개(/posts/
, /posts/10/
)의 URL을 대응할 수 있다.
from django.db import models
class Post(models.Model):
message = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
from rest_framework.serializers import ModelSerializer
from .models import Post
class PostSerializer(ModelSerializer):
class Meta:
model = Post
fields = '__all__'
from rest_framework.viewsets import ModelViewSet
from .serializers import PostSerializer
from .models import Post
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# def dispatch(self, request, *args, **kwargs):
"""
dispatch재정의 후, httpie요청의 --form옵션 유무에 따른 로그를 확인해볼 수 있다.
http POST :8000 message="hello world"
http --form POST :8000 message="hello world"
"""
# print("request.body:", request.body)
# print("request.POST:", request.POST)
# return super().dispatch(request, *args, **kwargs)
from django.urls import include, path
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register('post', views.PostViewSet) # 2개의 URL을 만들어 줍니다.
urlpatterns = [
path('', include(router.urls)),
]
http :8000 # 목록 조회
http --form POST :8000 message="hello world" # 새 포스팅 등록
http :8000/1/ # 1번 포스팅 조회
http --form PUT :8000/1/ message="hello django" # 1번 포스팅 수정
http :8000/1/ # 1번 포스팅 수정
http DELETE :8000/1/ # 1번 포스팅 삭제
http :8000 # 목록 조회
우리는 이 중에, HTTPie를 통해 주로 실습을 진행한다.
# pip install
pip install httpie
# poetry
poetry add --dev httpie
http GET 요청할주소 GET인자명==값 GET인자명==값
http --json POST 요청할주소 GET인자명==값 GET인자명==값 POST인자명=값 POST인자명=값
http --form POST 요청할주소 GET인자명==값 GET인자명==값 POST인자명=값 POST인자명=값
http PUT 요청할주소 GET인자명==값 GET인자명==값 PUT인자명=값 PUT인자명=값
http DELETE 요청할주소 GET인자명==값 GET인자명==값
--form
옵션 지정: multipart/form-data
--json
옵션을 지정하거나 생략: application/json
→ 요청 데이터를 JSON 직렬화http GET httpbin.org/get x==1 y==2 # GET 인자는 등호를 2개씩
http --form POST httpbin.org/post a=1 b=2 c=3 # POST 인자는 등호를 한개
http PUT httpbin.org/put hello=world
http DELETE httpbin.org/delete
DRF를 통해 중복을 줄이자