모델 필드에 해당하는 필드가 있는 Serializer 클래스를 자동으로 만들 수 있는 shorcut
아래 핵심 기능을 제공
Model의 필드를 어떻게 '직렬화' 할 지 설정하는 것이 핵심
이 과정은 Django에서 Model의 필드를 설정하는 것과 동일함
#articles/serializer.py
class ArticleListSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ('id','title')
#작성한 Serializer import
>>> from articles.serializers import ArticleListSerializer
#기본 인스턴스 구조 확인
>>> serializer = ArticleListSerializer()
>>> serializer
ArticleListSerializer():
id = IntegerField(label='ID', read_only=True)
title = CharField(max_length=100)
# Model instance 객체
>>> article = Article.objects.get(pk=3)
>>> article
<Article: Article object (3)>
#직렬화
>>> serializer = ArticleListSerializer(article)
>>> serializer
ArticleListSerializer(<Article: Article object (3)>):
id = IntegerField(label='ID', read_only=True)
title = CharField(max_length=100)
>>> serializer.data
{'id': 3, 'title': 'Along several increase teacher to wind kid stock.'}
>>> serializer = ArticleListSerializer(articles)
>>> serializer.data
Traceback (most recent call last):
File "C:\Users\SAMSUNG\Desktop\Django\07_DRF\01_drf\venv\lib\site-packages\rest_framework\fields.py", line 457, in get_attribute
return get_attribute(instance, self.source_attrs)
File "C:\Users\SAMSUNG\Desktop\Django\07_DRF\01_drf\venv\lib\site-packages\rest_framework\fields.py", line 97, in get_attribute
instance = getattr(instance, attr)
AttributeError: 'QuerySet' object has no attribute 'title'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\SAMSUNG\Desktop\Django\07_DRF\01_drf\venv\lib\site-packages\rest_framework\serializers.py", line 555, in data
ret = super().data
File "C:\Users\SAMSUNG\Desktop\Django\07_DRF\01_drf\venv\lib\site-packages\rest_framework\serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "C:\Users\SAMSUNG\Desktop\Django\07_DRF\01_drf\venv\lib\site-packages\rest_framework\serializers.py", line 509, in to_representation
attribute = field.get_attribute(instance)
File "C:\Users\SAMSUNG\Desktop\Django\07_DRF\01_drf\venv\lib\site-packages\rest_framework\fields.py", line 490, in get_attribute
raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `title` on serializer `ArticleListSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'title'.
>>>
#many =True 설정
>>> serializer = ArticleListSerializer(articles,many=True)
>>> serializer.data
[OrderedDict([('id', 3), ('title', 'Along several increase teacher to wind kid stock.')]), OrderedDict([('id', 4), ('title', '수정')]), OrderedDict([('id', 5), ('title', 'Major vote direction accept growth history.')]), OrderedDict([('id', 6), ('title', '제목')]), OrderedDict([('id', 7), ('title', 'title')])]
GET | POST | PUT | DELETE | |
---|---|---|---|---|
articles/ | 전체 글 조회 | 글 작성 | ||
articles/1/ | 1번 글 조회 | 1번 글 수정 | 1번 글 삭제 |
#urls.py
urlpatterns = [
path('articles/', views.article_list),
]
#views.py
def article_list(request) :
#쿼리셋 조회
articles = Article.objects.all()
# print(articles)
#직렬화하기 쿼리셋이니까 many=True
serializer = ArticleListSerializer(articles,many=True)
# print(serializer.data)
#전체 데이터를 가져오는 것
return Response(serializer.data)
__all__
로 설정#serializer.py
class ArticleSerializer(serializers.ModelSerializer) :
class Meta:
model = Article
fields = '__all__'
#urls.py
urlpatterns = [
path('articles/<int:article_pk>/', views.article_detail),
]
#views.py
@api_view(['GET'])
def article_detail(request, article_pk) :
article = get_object_or_404(Article,pk=article_pk)
serializer = ArticleSerializer(article)
return Response(serializer.data)
from rest_framework import status
@api_view(['GET','POST'])
def article_list(request) :
elif request.method == 'POST' :
#데이터를 넣어야 하기 때문에 키워드 인자로 데이터를 넣는다.
#첫번째 인자가 instance이기 때문에 data를 명시
serializer = ArticleSerializer(data=request.data)
#유효성검사 통과하면 201 CREATED status 반환
if serializer.is_valid() :
serializer.save()
return Response(serializer.data,status=status.HTTP_201_CREATED)
#유효성 검사 통과 못하면 BAD REQUEST
return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
DRF에는 status code를 보다 명확하고 읽기 쉽게 만드는데 사용할 수 있는 정의된 상수 집합을 제공
status 모듈에 HTTP status code 집합이 모두 포함되어 있음
단순히 status=201 같은 표현으로도 사용할 수 있지만 DRF는 권장하지 않음
#유효성검사 통과하면 201 CREATED status 반환
#raise_exeption을 통해 else구문을 사용하지 않아도 유효성 검사를 통과하지 못하면, 400 에러 리턴
if serializer.is_valid(raise_exception=True) :
serializer.save()
return Response(serializer.data,status=status.HTTP_201_CREATED)
# #유효성 검사 통과 못하면 BAD REQUEST
# return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET','DELETE'])
def article_detail(request, article_pk) :
article = get_object_or_404(Article,pk=article_pk)
elif request.method=='DELETE' :
article.delete()
#response에는 넘겨줄 값이 필요한데, 삭제는 이가 없으므로 직접 만들어줌
data = {
#pk는 url에서 가져온 article_pk이다.
'delete' : f'데이터 {article_pk}번이 삭제 되었습니다.'
}
return Response(data, status=status.HTTP_204_NO_CONTENT)
@api_view(['GET','DELETE','PUT'])
def article_detail(request, article_pk) :
elif request.method=='PUT' :
serializer = ArticleSerializer(article,data=request.data)
if serializer.is_valid(raise_exception=True) :
serializer.save()
return Response(serializer.data)