본문 바로가기
FrameWork/Django

DRF POST & validate & save

by mansoorrr 2024. 7. 18.

[** post ** ]

DRF는 기본적으로 GET요청을 갖는다.

post, put, delete 등 다른 method를 사용하기 위해서는 아래와 같이 사용한다.

@api_view(['GET', 'POST])
def all_categories(request):
	if request.method == 'GET':
            all_category = Category.objects.all()
            serializer = CategorySerializer(all_category, many=True)
            return Response(serializer.data)
        elif request.method == 'POST':
            return Response({'post': True})

 

POST의 경우 데이터를 CREATE하는 역할이다. 즉 클라이언트가 화면에서 입력한 데이터를 백엔드에서 받아 데이터베이스에 저장해야 한다. 이 경우 request.data를 이용한다. 코드는 다음과 같이 바뀐다. 화면에서는 dictionay형태로 들어오기 때문에 백엔드에서는 request.data['key'] 형식으로 출력 가능하다.

 

[** validate **]

  • 화면에서 데이터를 받아 db에 저장하기 위해서도 serializer가 필요(form의 역할)
  • post일때 serializer를 사용하기 위해서는 data=request.data라고 작성
  • pk, created_at과 같이 자동으로 부여되는 필드의 경우는 read_only=True를 통해(get일경우만 사용됨) 화면에서 입력되어야 하는 것이 아님을 명시
  • 이렇게 post를 통해 들어오는 데이터의 경우 serializer를 통해 validation을 진행 할 수 있음
  • valication이 옳게 되었는지 여부는 serializer.is_valid()를 통해 확인 가능
#---------- categories/serializers.py
from categories.models import Category

class CategorySerializer(serializers.Serializer):
	pk = serializers.IntegerField(read_only=True)
    name = serializers.CharField(max_length=50, required=True..) #더 많은 조건 입력 가능
    kind = serializers.CharField(choices=Category.CategoryKindChoices.choices,) #choice도 사용
    created_at = serializers.DateTimeField(read_only=True)
    

#---------- categories/views.py
@api_view(['GET', 'POST'])
def all_categories(request):
    if request.method == 'GET':
        all_category = Category.objects.all()
        serializer = CategorySerializer(all_category, many=True)
        return Response(serializer.data)
    elif request.method == 'POST':
    	#화면에서 입력 > post 누르면 백으로 들어오는 데이터 모양
        #{'name': <입력값>, 'kind': <입력값}
        
        name = request.data['name']
        kind = request.data['kind']
        return Response({'created':True})

 

[** save ** ]

  • post로 입력을 받고 serializer를 통해 validation을 마쳤다면
  • db에 저장할 차례
  • 원래는 model.objects.create를 바로 사용했겠지만
  • serializer의 경우는 save()메서드를 제공함
  • save() 매서드가 실행되려면 serializers.py에 create매서드가 있어야만 함(호출)
#---------- categories/views.py
@api_view(['GET', 'POST'])
def all_categories(request):
    if request.method == 'GET':
        all_category = Category.objects.all()
        serializer = CategorySerializer(all_category, many=True)
        return Response(serializer.data)
    elif request.method == 'POST':
        serializer = CategorySerializer(data=request.data)
        if serializer.is_valid():
            new_category = serializer.save() #save를 통해 새로운 category 반환
            return Response(CategorySerializer(new_category).data) #다시 serializer를 통해 화면에 반환
        else:
            return Response(serializer.errors)   


#----------- categories/serializers.py
class CategorySerializer(serializers.Serializer):
    pk = serializers.IntegerField(read_only=True)
    name = serializers.CharField()
    kind = serializers.ChoiceField(        
        choices=Category.CategoryKindChoice.choices,
    )
    created_at = serializers.DateTimeField(read_only=True)
	
    #views.py에서 serializers가 save될때 호출됨
    def create(self, validated_data):
        return Category.objects.create(**validated_data)
        
        '''
        **validated_data
          - 들어오는 validated_data는 {"name": "value", "kind": "value"} 형식으로 들어옴
          - **를 써주게 되면 name="value", kind="value" 형식으로 변환해줌
          - 개발자의 편의성 향상        
        '''

 

'FrameWork > Django' 카테고리의 다른 글

DRF APIView  (0) 2024.07.18
DRF UPDATE * DELETE  (0) 2024.07.18
DRF(Django Rest Framework)  (0) 2024.07.17
Templates Rendering  (0) 2024.07.17
URL & views  (0) 2024.07.17