μ§λ κΈ
[Django REST framework] (1) νλ‘μ νΈ μμ±κ³Ό μ€μ
Django REST framework
λ₯Ό μ΄μ©ν΄ κ°λ°ν λ λ±μ₯νλ μ£Όμ μ»΄ν¬λνΈμ λν΄μ μ΄ν΄νκ³ μ¬μ©λ²μ μμ보μ.
Serializer
Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into
JSON
,XML
or other content types. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.
Django REST framework API Guide - Serializer
Serializer
λ μ΄λ¦μμ μ§μν μ μλ―μ΄ νΉμ ν ꡬ쑰μ λ°μ΄ν°(κ°μ²΄, Queryset
λ±)λ₯Ό Python
μ dictionary
λ‘ λ³ννλ κΈ°λ₯(μ§λ ¬ν, Serialization)μ μ 곡νλ€. μμΌλ‘ Python
μ dictionary
λ₯Ό μλ ꡬ쑰μ λ°μ΄ν°λ‘ μλ³ννλ(μμ§λ ¬ν, Deserialization) κΈ°λ₯λ μ 곡νλ€.
Serializer
μ μμ μ§λ ¬ν(Serialization)
κ²μκΈμ μ 보λ₯Ό νννλ Post
λΌλ μ΄λ¦μ ν΄λμ€κ° μλ€.
class Post
def __init__(self, title, content):
self.title = title
self.content = content
μ΄ post
κ°μ²΄μ νλ title
κ³Ό content
λ₯Ό ν΅ν΄ κ²μκΈμ μ λͺ©κ³Ό λ΄μ© κ°μ μ΄μ©ν μ μλ€.
>>> post = Post(title='This is post', content='Hello world!')
>>> post.title
'This is post'
>>> post.content
'Hello world!'
μ΄λ₯Ό μ§λ ¬ννλ Serializer
λ₯Ό λ€μκ³Ό κ°μ΄ μ μν μ μλ€.
from rest_framework import serializers
class PostSerializer(serializers.Serializer):
title = serializers.CharField()
content = serializers.CharField()
Serializer
λ₯Ό μ΄μ©ν΄ κ°μ²΄μ ꡬ쑰μ μ μ¬ν dictionary
κ°μ²΄λ₯Ό μ»μ μ μλ€. Serializer
μ νλλ₯Ό μ μν λ λ³λ€λ₯Έ μ΅μ
μ΄ μλ€λ©΄ λμΌν νλ μ΄λ¦μ μ΄μ©ν΄ μμ± μ μ λ¬λ κ°μ²΄(post
)μ νλ κ°μ μ΄μ©νλ€.
>>> serializer = PostSerializer(post)
>>> serializer.data
{'title': 'This is post', 'content': 'Hello world!'}
μλμ post
κ°μ²΄μ λΉκ΅ν΄λ³΄μ. νλ μ΄λ¦μ ν΅ν΄ κ°μ μ΄μ©νλ κ°μ²΄μ μ μ¬ν ꡬ쑰μ dictionary
λ₯Ό μ»μ μ μμμ νμΈν μ μλ€.
>>> # post κ°μ²΄
>>> post.title
'This is post'
>>> post.content
'Hello world!'
>>> # μ§λ ¬νλ λ°μ΄ν° (dictionary)
>>> serializer.data['title']
'This is post'
>>> serializer.data['content']
'Hello world!'
title
κ³Ό content
λΌλ λμΌν μ΄λ¦μ νλλ₯Ό μ΄μ©ν μ μλ λ€μ Model
μ μΈμ€ν΄μ€λ Serializer
λ₯Ό μ΄μ©ν΄ μ§λ ¬νλ₯Ό ν μ μλ€.
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=1024)
content = models.TextField()
>>> post = Post.objects.create(title='This is post', content='Hello world!')
>>> serializer = PostSerializer(post)
>>> serializer.data
{'title': 'This is post', 'content': 'Hello world!'}
μμ§λ ¬ν(Deserialization)μ κ°μ²΄ μ μ₯
Serializer
λ μ§λ ¬νμ λ°λλ‘ dictionary
κ°μ²΄λ₯Ό μ΄μ©ν΄ μλμ κ°μ²΄λ₯Ό μ»μ΄λ΄λ μμ§λ ¬νμ κΈ°λ₯λ μ 곡νλ€. μ§λ ¬ν κ³Όμ κ³Ό λ¬λ¦¬ μμ§λ ¬νλ₯Ό μν΄μ Serializer
λ₯Ό μμ±ν λ data
μΈμλ‘ dictionary
κ°μ²΄λ₯Ό λ°λμ μ λ¬ν΄μΌ νλ€. Serializer
λ₯Ό μμ± ν λ€μλ is_valid()
ν¨μλ₯Ό νΈμΆν΄ κ° νλμ μ 체 λ°μ΄ν°μ μ ν¨μ±μ κ²μ¦ ν΄μΌνλ€. validated_data
λ κ°μ²΄μ μμ±, μ μ₯, μμ λ±μ μμ
μ μ΄μ©λλ©°, is_valid()
ν¨μλ₯Ό ν΅ν΄ μ ν¨μ±μ κ²μ¦νμ§ μμΌλ©΄ ν΄λΉ μμ
μ μ§νν μ μλ€. μ¦ κ°μ²΄μ μμ±, μ μ₯, μμ μ μμ λ°λμ is_valid()
ν¨μλ₯Ό νΈμΆν΄μΌ νλ€.
>>> post_data
{'title': 'This is post', 'content': 'Hello world!'}
>>> serializer = PostSerializer(data=post_data)
>>> serializer.is_valid()
True
>>> serializer.validated_data
{'title': 'This is post', 'content': 'Hello world!'}
κ°μ²΄μ μμ±κ³Ό μ μ₯μ μν΄μ create()
, update()
λ₯Ό μ€λ²λΌμ΄λ ν΄μΌνλ€. λ ν¨μλ μΈμλ‘ validated_data
λ₯Ό μ λ¬λ°λλ€. μ΄λ is_valid()
ν¨μλ₯Ό ν΅ν΄ μ ν¨μ±μ΄ λͺ¨λ κ²μ¦λ κ°μ dictionary
μ΄λ€. create()
λ validated_data
λ₯Ό μ΄μ©ν΄ μμ±ν κ°μ²΄λ₯Ό λ°ννλλ‘, κ·Έλ¦¬κ³ update()
λ validated_data
λ₯Ό μ΄μ©ν΄ instance
λ₯Ό μμ ν λ€ λ°ννλλ‘ μ μνλ€.
class PostSerializer(serializers.Serializer):
title = serializers.CharField()
content = serializers.CharField()
def create(self, validated_data):
return Post(
title=validated_data['title'],
content=validated_data['content']
)
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.content = validated_data.get('content', instance.content)
return instance
Serializer
λ Model
κ³Ό ν¨κ» μ¬μ©λλ κ²½μ°κ° λ§λ€. μλλ₯Ό μμ μ½λμ λΉκ΅νμλ©΄ model manager
λ₯Ό μ΄μ©ν΄ model instance
λ₯Ό μμ±ν΄ λ°ννλ λΆλΆ, μμ μ΄ν save()
λ₯Ό μ΄μ©ν΄ μ μ©ν λΆλΆμ΄ μΆκ°λμλ€.
class PostSerializer(serializers.Serializer):
title = serializers.CharField()
content = serializers.CharField()
def create(self, validated_data):
return Post.objects.create(
title=validated_data['title'],
content=validated_data['content']
)
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.content = validated_data.get('content', instance.content)
isinstance.save()
return instance
μμ λ§νλ μ ν¨μ± κ²μ¬λ₯Ό νλλ³λ‘, λν κ°μ²΄ μ 체 μμ€μμ μ€λ²λΌμ΄λν μ μλ€. νΉμ νλμ λν μ ν¨μ± κ²μ¬λ₯Ό μ€λ²λΌμ΄λ νκ³ μ νλ€λ©΄, validate_${field_name}(self, value)
λ₯Ό μ€λ²λΌμ΄λνλ©΄ λλ€. λ§μ½ μ λͺ©(title
)μ κΈΈμ΄κ° 100 μ΄νμΈ κ²½μ°μ λν΄μλ§ μ ν¨νλ€ νμ νκ³ μΆλ€λ©΄ λ€μμ²λΌ ꡬννλ€. μ ν¨νλ€λ©΄ ν΄λΉ κ°μ λ°ννκ³ κ·Έλ μ§ μλ€λ©΄ μμΈλ₯Ό λμ§λλ‘ κ΅¬ννλ€.
def validate_title(self, value):
if len(value) <= 100:
return value
raise ValueError('μ λͺ©μ κΈΈμ΄λ 100μ΄νμ¬μΌ ν©λλ€.')
ViewSet
Django REST framework allows you to combine the logic for a set of related views in a single class, called a
ViewSet
Django REST framework API Guide - Viewsets
ViewSet
μμ class-based view
μ΄λ HTTP method
κΈ°λ°μ νΈλ€λ¬λ₯Ό μ 곡νλ APIView
μ λ¬λ¦¬ μμμ λν λμ κΈ°λ°μ νΈλ€λ¬μΈ list
, create
, retrieve
λ±μ μ 곡νλ€.
μμ μμ μμ μ΄μ©νλ Post model
μ κ³μ μ΄μ©νμ.
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=1024)
content = models.TextField
Post model
μ μμ±, μ‘°ννλ ViewSet
μ λ€μμ²λΌ μ μνλ€.
from rest_framework.viewsets import ViewSet
class PostViewset(ViewSet):
def create(self, request):
serializer = PostSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
def list(self, request):
queryset = Post.objects.all()
serializer = PostSerializer(queryset, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
queryset = User.objects.all()
serializer = UserSerializer(user)
return Response(serializer.data)
ViewSet
μμ μ 곡νλ λμμ λ€μκ³Ό κ°λ€.
from rest_framework.viewsets import ViewSet
class PostViewset(ViewSet):
def list(self, request):
pass
def create(self, request):
pass
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
ViewSet
μμ as_view
ν¨μλ₯Ό μ΄μ©ν΄ νΉμ view
λ₯Ό μΆμΆν μ μλ€. HTTP method
μ λμμ μ΄λ¦μ΄ λ§€νλ dictionaryλ₯Ό μΈμλ‘ μ λ¬νλ€.
post_list = PostViewset.as_view({'get': 'list', 'post': 'create'})
post_detail = PostViewset.as_view({'get': 'retrieve'})
μμμ μΆμΆν view
λ₯Ό μ΄μ©ν΄ URLConf
λ₯Ό μ€μ ν μ μλ€.
urlpatterns = [
...
path('posts/', post_list),
path('posts/<int:pk>', post_detail),
...
]
Router
ViewSet
μ μ΄μ©ν΄ view
λ₯Ό μΆμΆνλ κ³Όμ μ μκ°ν΄λ³΄μ. μμμ λν CRUDλ₯Ό μ 곡νλ APIμ μμ£Ό λ±μ₯νλ URL ν¨ν΄κ³Ό λμμ΄ μμμ μ μΆν μ μλ€. κ·Έλ¦¬κ³ μ΄λ¬ν ν¨ν΄μ λ§μΆμ΄ view
μ URL ν¨ν΄μ κΈ°λ³ΈμΌλ‘ λ§€μΉν΄μ£Όλ νΈμ κΈ°λ₯μ Router
κ° μ 곡νλ€. λ€μ λ μ½λλ λμΌν λμμ μννλ€.
from posts.views import PostViewSet
post_list = PostViewSet.as_view({
'get': 'list',
'post': 'create'
})
post_detail = PostViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy'
})
urlpatterns = [
path('posts/', post_list),
path('posts/<int:pk>', post_detail),
]
from django.urls import include, path
from rest_framework.routers import DefaultRouter
from posts.views import PostViewSet
router = DefaultRouter()
router.register(r'posts', PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
REST framework λ§μ μ΄μ©ν κ°λ¨ν μμ
μμμ μ€λͺ
ν μ»΄ν¬λνΈλ€μ μΌλ°μ μΌλ‘ Model
κ³Ό ν¨κ» μ¬μ©λλ κ²½μ°κ° λ§μΌλ©°, Model
μ μ΄μ©ν΄ ν΄λΉ μ»΄ν¬λνΈλ€μ μ μν λ μμ£Ό λ±μ₯νλ ν¨ν΄λ€μ΄ 미리 μ μλμμλ€. μ΄λ₯Ό μ΄μ©ν΄ μμ£Ό μ§§μ μ½λλ§μΌλ‘λ μνλ κΈ°λ₯μ APIλ₯Ό κΈλ°© ꡬνν μ μλ€.
μμμ μ¬μ©νλ Post model
μ CRUDλ₯Ό ν μ μλ APIλ₯Ό μμ±ν΄λ³΄μ.
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=1024)
content = models.TextField()
from rest_framework import serializers
from models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fiedls = ['id', 'title', 'content']
from rest_framework.viewsets import ModelViewSet
from posts.serializers import PostSerializer
from models import Post
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
from django.urls import include, path
from rest_framework.routers import DefaultRouter
from posts.views import PostViewSet
router = DefaultRouter()
router.register(r'posts', PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
'Web Programming > Django' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Django REST framework] (4) JWT μΈμ¦, Kakao μμ λ‘κ·ΈμΈ (0) | 2024.08.26 |
---|---|
[Django REST framework] (3) Nginx, Gunicorn, AWS EC2 λ°°ν¬ (0) | 2024.08.26 |
[Django REST framework] (1) νλ‘μ νΈ μμ±κ³Ό μ€μ (2) | 2024.07.12 |