JUST DO IT!

[TIL]KDT_20230426 ๋ณธ๋ฌธ

TIL

[TIL]KDT_20230426

sunhokimDev 2023. 4. 26. 17:01

๐Ÿ“š KDT WEEK 4 DAY 2 TIL

  • Serializer
    • ModelSerializer
  • HTTP Methods
    • GET
    • POST
    • PUT, DELETE
  • APIView

 


 

๐ŸŸฅ Serializer

๋‹ค์Œ์˜ ๋‘ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ

Serialize : ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค๋‚˜ QuerySet ๋ฐ์ดํ„ฐ๋ฅผ JSON ํ˜•์‹์˜ ํŒŒ์ผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ž‘์—…

Deserialize : JSON ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ž‘์—…

 

๋‹ค์‹œ๋งํ•ด, Serializer๋Š” ์šฐ๋ฆฌ๊ฐ€ Django์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํŒŒ์ด์ฌ ๊ฐ์ฒด๋‚˜ ์ฟผ๋ฆฌ์…‹ ๊ฐ™์ด ๋ณต์žกํ•œ ๊ฐ์ฒด๋“ค์„ Rest API์—์„œ ์‚ฌ์šฉํ•  ๊ฐ„๋‹จํ•œ JSON ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค!

Rest API : ์ž์›์„ ์ด๋ฆ„์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ํ•ด๋‹น ์ž์›์˜ ์ƒํƒœ๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š” ๋ชจ๋“  ๊ฒƒ(CRUD)

DRF : Django REST Framework

 

 

Question ๋ชจ๋ธ Serializer ๊ตฌํ˜„ํ•˜๊ธฐ

polls_api/serializer.py

from rest_framework import serializers
from polls.models import Question

class QuestionSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True) # read_only๋ฅผ ๋„ฃ์–ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์†์„ฑ์€ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ๋งŒ๋“ฆ
    question_text = serializers.CharField(max_length=200)
    pub_date = serializers.DateTimeField(read_only=True)

    def create(self, validated_data): # validated์ธ ์ด์œ ๋Š” serializer๊ฐ€ is_valid()๋ฅผ ๋จผ์ € ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ
        return Question.objects.create(**validated_data)

	# id์™€ pub_date๋Š” ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋ฏ€๋กœ question_text๋งŒ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.
    def update(self, instance, validated_data):
        instance.question_text = validated_data.get('question_text', instance.question_text)
        instance.save()
        return instance
  • ๋ชจ๋ธ์—์„œ ์†์„ฑ์„ ์ •์˜ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ํƒ€์ž…์— ๋งž๋Š” ํ•„๋“œ์™€ ์ œํ•œ ์กฐ๊ฑด์„ ์ ์–ด์•ผ ํ•œ๋‹ค.
  • serializer๋Š” ๋„˜์–ด์˜จ data๊ฐ€ ์ œํ•œ ์กฐ๊ฑด ๋“ฑ์„ ๋งŒ์กฑํ–ˆ๋Š”์ง€๋ฅผ ํ•ญ์ƒ ๋จผ์ € ์ฒดํฌํ•˜๊ธฐ ์œ„ํ•ด .is_valid()๋ฅผ ๋™์ž‘ํ•ด์•ผํ•œ๋‹ค.
    • ์ด ๋ถ€๋ถ„์€ ๋ฐ‘์—์„œ ๋” ์„ค๋ช…ํ•˜๊ฒ ๋‹ค.
  • ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์†์„ฑ์€ ์ œํ•œ ์กฐ๊ฑด์— read_only ์กฐ๊ฑด์„ ๊ผญ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค.

 

์ด๊ฑธ Shell์—์„œ ์‹ค์ œ๋กœ Serializer๊ฐ€ ๋™์ž‘ํ•˜๋Š”์ง€ ์ฒดํฌํ•ด๋ดค๋‹ค.

 

๋จผ์ € ๋ฐ์ดํ„ฐ ํ•˜๋‚˜๋ฅผ Serialize ํ•ด๋ณด๋Š” ์‹ค์Šต์ด๋‹ค.

# ๊ด€๋ จ ํ•จ์ˆ˜๋ฅผ ๋ชจ๋‘ importํ–ˆ๊ณ , q๋Š” Question์˜ ํ•œ ์˜ค๋ธŒ์ ํŠธ๋ผ๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.
>>> q
<Question: ์ œ๋ชฉ: ํœด๊ฐ€๋ฅผ ์–ด๋””์„œ ๋ณด๋‚ด๊ณ  ์‹ถ์œผ์„ธ์š”?, ๋‚ ์งœ: 2023-04-24 08:15:31+00:00>

>>> serializer = QuestionSerializer(q)
>>> serializer.data
{'id': 1, 'question_text': 'ํœด๊ฐ€๋ฅผ ์–ด๋””์„œ ๋ณด๋‚ด๊ณ  ์‹ถ์œผ์„ธ์š”?', 'pub_date': '2023-04-24T08:15:31Z'}

>>> json_str = JSONRenderer().render(serializer.data)
>>> json_str
b'{"id":1,"question_text":"\xed\x9c\xb4\xea\xb0\x80\xeb\xa5\xbc \xec\x96\xb4\xeb\x94\x94\xec\x84\x9c \xeb\xb3\xb4\xeb\x82\xb4\xea\xb3\xa0 \xec\x8b\xb6\xec\x9c\xbc\xec\x84\xb8\xec\x9a\x94?","pub_date":"2023-04-24T08:15:31Z"}'

์•„๊นŒ ์ž‘์„ฑํ–ˆ๋˜ QuestionSerializer๋ฅผ ํ†ตํ•ด ์˜ค๋ธŒ์ ํŠธ q๋ฅผ ์ถœ๋ ฅํ•ด๋ณด๋ฉด, Dict ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚˜์˜จ๋‹ค. >  JSON ํƒ€์ž…

JSONRenderer๋กœ ์ด serializer ๋ฐ์ดํ„ฐ๋ฅผ ๋ Œ๋”๋งํ•˜๋ฉด, ์ปดํ“จํ„ฐ์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์ธ string ํ˜•ํƒœ๋กœ ๋ฐ”๋€Œ์–ด์ง„๋‹ค.

 

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ Serialize ์ˆ˜ํ–‰์ด๋‹ค!

 

๋‹ค์Œ์œผ๋กœ Deserialize์„ ์ˆ˜ํ–‰ํ•ด๋ณด๋ฉด..

>>> import json
>>> data = json.loads(json_str)
>>> data
{'id': 1, 'question_text': 'ํœด๊ฐ€๋ฅผ ์–ด๋””์„œ ๋ณด๋‚ด๊ณ  ์‹ถ์œผ์„ธ์š”?', 'pub_date': '2023-04-24T08:15:31Z'}

>>> serializer = QuestionSerializer(data=data)
>>> serializer.is_valid()  
True

>>> serializer.validated_data 
OrderedDict([('question_text', 'ํœด๊ฐ€๋ฅผ ์–ด๋””์„œ ๋ณด๋‚ด๊ณ  ์‹ถ์œผ์„ธ์š”?')])

>>> new_question = serializer.save() # Create
>>> new_question
<Question: ์ œ๋ชฉ: ํœด๊ฐ€๋ฅผ ์–ด๋””์„œ ๋ณด๋‚ด๊ณ  ์‹ถ์œผ์„ธ์š”?, ๋‚ ์งœ: 2023-04-24 08:15:31+00:00>

>>> data={'question_text': '์ œ๋ชฉ์ˆ˜์ •'}
>>> serializer = QuestionSerializer(new_question, data=data) 
>>> serializer.is_valid()  
True

>>> serializer.save() # Update
<Question: ์ œ๋ชฉ: ์ œ๋ชฉ์ˆ˜์ •, ๋‚ ์งœ: 2023-04-26 15:23:55+00:00>

 

  • json.loads()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ string ํƒ€์ž…์„ ๋‹ค์‹œ json์œผ๋กœ ๋ฐ”๊ฟ” ์ค„ ์ˆ˜ ์žˆ๋‹ค.
  • QuestionSerializer์— ๋ฐ์ดํ„ฐ ์ธ์ž๋ฅผ ํ•˜๋‚˜ ๋„ฃ๊ณ , is_valid()ํ•œ์ง€ ๊ผญ ์ฒดํฌํ•ด์ค˜์•ผํ•œ๋‹ค. (๊ทธ๋ž˜์•ผ ๋‹ค์Œ ๋™์ž‘์ด ๊ฐ€๋Šฅํ•˜๋‹ค)
  • serializer๋Š” ํŠน์ดํ•˜๊ฒŒ ์ผ๋ฐ˜ Dict ํ˜•ํƒœ๊ฐ€ ์•„๋‹Œ, ์ž…๋ ฅํ•œ ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅํ•˜๋Š” OrderedDict๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • .save()์˜ ๊ฒฝ์šฐ, QuestionSerializer์˜ ์ธ์ž๋กœ ๋ฌด์—‡์„ ๋ฐ›์•˜๋Š”์ง€์— ๋”ฐ๋ผ Create์™€ Update์„ ๊ตฌ๋ถ„ํ•œ๋‹ค!
  • is_valid()์—์„œ False๋ฅผ ๋ฐ›์•˜์„ ๊ฒฝ์šฐ, serializer.errors๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ์–ด๋–ค ์—๋Ÿฌ์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 


 

ModelSerializer

 

์œ„์—์„œ ๊ตฌํ˜„ํ•œ Serializer๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

from rest_framework import serializers
from polls.models import Question

class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Question
        fields = ['id', 'question_text', 'pub_date'] # ModelSerializer๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ

์•„๊นŒ ๊ตฌํ˜„ํ–ˆ๋˜ ์ฝ”๋“œ๋ณด๋‹ค ํ›จ~์”ฌ ๊ฐ„๋‹จํ•˜๊ณ  ์‰ฝ๋‹ค.

ModelSerializer๋ฅผ ์ƒ์†๋ฐ›๊ณ , Meta ํด๋ž˜์Šค์— ๊ตฌํ˜„ํ•  Model๊ณผ ์†์„ฑ๋“ค์„ ์ž…๋ ฅํ•ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.

๋ฌผ๋ก  ์•„๊นŒ Shell์—์„œ์˜ ๋ช…๋ น์–ด๋ฅผ ๋ชจ๋‘ ๋˜‘๊ฐ™์ด ์ˆ˜ํ–‰ํ•œ๋‹ค.

 


๐ŸŸฆ HTTP Methods

์ฃผ์–ด์ง„ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•˜๊ธธ ์›ํ•˜๋Š” ํ–‰๋™์„ ๊ณจ๋ผ ๋ณด๋‚ด์•ผํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฆฌ์†Œ์Šค๋Š” Question, Choice ๋“ฑ์„ ๋งํ•œ๋‹ค.

์ด ๋ฐฉ๋ฒ•์€ ์‚ฌ์šฉ์ž์˜ ์ž…์žฅ์—์„œ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค!

  • GET : ์ •๋ณด์˜ ํš๋“ ,ํŠน์ • ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•  ๋•Œ > READ
  • POST : ์–ด๋–ค ์ •๋ณด๋ฅผ ์„œ๋ฒ„์— ๋„˜๊น€, ๋ฌด์–ธ๊ฐ€ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค ๋•Œ ์“ฐ์ผ ๋•Œ > CREATE
  • PUT : ๋‚ด์šฉ์˜ ์ˆ˜์ • ์š”์ฒญ > UPDATE
  • DELETE : ํŠน์ • ๋ฆฌ์†Œ์Šค์˜ ์‚ญ์ œ

๋” ๋งŽ์€ Methods๋Š” https://developer.mozilla.org/ko/docs/Web/HTTP/Methods ๋ฅผ ์ฐธ๊ณ 

 


GET

๋จผ์ €, views.py์— GET์„ ๊ตฌํ˜„ํ•ด๋ณธ๋‹ค.

 

polls_api/views.py

from rest_framework.decorators import api_view
from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework.response import Response

@api_view() # ๊ด„ํ˜ธ์•ˆ์ด ๋น„์–ด์žˆ์œผ๋ฉด GET
def question_list(request):
    questions = Question.objects.all()
    serializer = QuestionSerializer(questions, many=True) # many ์˜ต์…˜์„ ์ฃผ๋ฉด, questions์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ค„์ˆ˜์žˆ์Œ
    return Response(serializer.data)

@api_view ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌํ˜„์€ ์‰ฌ์šดํŽธ์ด๋‹ค. ๊ธฐ๋ณธ์ ์ธ ์›น ์ธํ„ฐํŽ˜์ด์Šค๋„ ๊ฐ€์ง€๊ณ ์žˆ๋‹ค.(DRF api)

 

views.py๋ฅผ ๊ตฌํ˜„ํ–ˆ์œผ๋‹ˆ url์„ ์—ฐ๊ฒฐํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

polls_api/urls.py์—

path('question/',question_detail, name='question_detail'),

๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ ,

 

๊ฐ€์žฅ ์ƒ์œ„ urls.py์—

path('rest/', include('polls_api.urls')),

๋„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

 

์ด๋ ‡๊ฒŒ ์ •์˜ํ•ด์ฃผ๋ฉด, http://127.0.0.1:8000/rest/question/ ๋กœ ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค!

 

๊ฐ„๋‹จํ•œ ์ฝ”๋“œ์—๋„, ์ด๋ ‡๊ฒŒ ํŽธํ•˜๊ฒŒ ๊ธฐ๋ณธ ์›น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง€์›ํ•ด์ค€๋‹ค.

 


POST

์•„๊นŒ GET์˜ views.py ์ฝ”๋“œ์—์„œ POST ๋ถ€๋ถ„๋งŒ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค.

from rest_framework.decorators import api_view
from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework.response import Response
from rest_framework import status # HTTP status

@api_view(['GET','POST']) # ์ด๋ฒˆ์—” POST๋„ ํ•„์š”ํ•˜๋‹ˆ, ํ•„์š”ํ•œ ๋ฐฉ์‹์„ ๋ชจ๋‘ ์ ์–ด์ค€๋‹ค.
def question_list(request):
    if request.method == 'GET': # ์‚ฌ์šฉํ•œ ๋ฐฉ์‹์— ๋”ฐ๋ผ ์ฝ”๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค.
        questions = Question.objects.all()
        serializer = QuestionSerializer(questions, many = True)
        return Response(serializer.data)
    
    if request.method == 'POST':
        serializer = QuestionSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

ํฌ๊ฒŒ ๋ณ€ํ•œ ์ ์€ ์—†๋‹ค.

api_view์— POST๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๊ณ  ๋ช…์‹œํ•˜๊ณ , ์‚ฌ์šฉํ•œ ๋ฐฉ์‹์— ๋”ฐ๋ผ ์ฝ”๋“œ๋ฅผ ๋‚˜๋ˆ„์—ˆ๋‹ค.

POST ๋ฐฉ์‹์—์„œ๋Š” request๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•˜์„ํ…Œ๋‹ˆ, ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ํ†ตํ•ด save ์ž‘์—…์„ ํ•œ๋‹ค.

์ถ”๊ฐ€๋กœ Response๋ฅผ ํ†ตํ•ด HTTP status๋„ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌํ•ด์ฃผ์—ˆ๋‹ค.

 

๊ฐ™์€ ํŽ˜์ด์ง€ ํ•˜๋‹จ์— POSTํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ์ƒ๊ฒผ๋‹ค! POST ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด, ์ƒˆ๋กœ์šด ์งˆ๋ฌธ์ด ์ƒ์„ฑ๋œ๋‹ค.

 


 

PUT, DELETE

 

์ด๋ฒˆ์—” ์•„๊นŒ question/ ํŽ˜์ด์ง€์—์„œ ํ•ด๋‹น id์˜ ๋ฒˆํ˜ธ๋กœ ํ•ด๋‹นํ•˜๋Š” detail ํŽ˜์ด์ง€๊นŒ์ง€ ๊ตฌํ˜„ํ•œ๋‹ค.

from django.shortcuts import get_object_or_404

@api_view(['GET', 'PUT', 'DELETE']) # ์ •๋ณด์˜ ์กฐํšŒ, ํŽธ์ง‘, ์‚ญ์ œ ๊ธฐ๋Šฅ
def question_detail(request, id):
    question = get_object_or_404(Question, pk=id) # primary key ๊ฐ€ id์ธ~

    if request.method == 'GET':
        serializer = QuestionSerializer(question)
        return Response(serializer.data) # question id๋กœ ์š”์ฒญ๋ฐ›์œผ๋ฉด ๋ฐ์ดํ„ฐ ๋ฑ‰๊ธฐ
    if request.method == 'PUT':
        serializer = QuestionSerializer(question, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        
    if request.method == 'DELETE':
        question.delete()
        return Response(status=status.HTTP_204_NO_CONTENT) # ๋ฐ์ดํ„ฐ๊ฐ€ ์ž˜ ์ง€์›Œ์ง 204

GET, POST์—์„œ ๊ตฌํ˜„ํ•œ views.py์— ์ถ”๊ฐ€ํ•œ ์ฝ”๋“œ๋งŒ ์ž‘์„ฑํ•˜์˜€๋‹ค.

์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋ฅผ ์œ„ํ•ด ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋ฟ, POST์™€ ๋ฐฉ์‹์€ ๋™์ผํ•˜๋‹ค.

๋‹จ, ๊ฐ๊ฐ์˜ HTTP Methods์˜ ๋™์ž‘์„ ๊ณ ๋ คํ•ด์„œ QuestionSerializer์— ๋„ฃ์„ ์ธ์ž ๋“ฑ์„ ์ƒ๊ฐํ•˜๊ณ  ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

+ ์ถ”๊ฐ€๋กœ ํ•ด๋‹น id๊ฐ€ ์—†์„ ๋•Œ๋ฅผ ๋Œ€๋น„ํ•œ get_object_or_404 ํ•จ์ˆ˜๋กœ question์„ ๊ฐ€์ ธ์˜ค๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

 

์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋ฅผ ์œ„ํ•œ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์œผ๋ฏ€๋กœ, urls.py์— ์ƒˆ๋กœ์šด path๋ฅผ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

    path('question/<int:id>/',question_detail, name='question_detail'),

 

Detail ํŽ˜์ด์ง€์— ์ ‘์†ํ•œ ๋ชจ์Šต. PUT๊ณผ DELETE ๋ฒ„ํŠผ์ด ๋ณด์ธ๋‹ค!

 


 

๐ŸŸจ APIView

๋ฐฉ๊ธˆ ๊ตฌํ˜„ํ–ˆ๋˜ HTTP Methods๋ฅผ ๋”์šฑ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๋„๋ก ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค!

 

from rest_framework.views import APIView

# ๊ฐ HTTP Methods์„ ํ•จ์ˆ˜๋กœ ๊ตฌ๋ณ„ํ•˜์—ฌ ๊ตฌํ˜„ํ•œ๋‹ค.
class QuestionList(APIView):
    def get(self, request):
        questions = Question.objects.all()
        serializer = QuestionSerializer(questions, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = QuestionSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class QuestionDetail(APIView):
    def get(self, request, id):
        question = get_object_or_404(Question, pk=id) # primary key ๊ฐ€ id์ธ~
        serializer = QuestionSerializer(question)
        return Response(serializer.data) # question id๋กœ ์š”์ฒญ๋ฐ›์œผ๋ฉด ๋ฐ์ดํ„ฐ ๋ฑ‰๊ธฐ    
    
    def put(self, request, id):
        question = get_object_or_404(Question, pk=id)  
        serializer = QuestionSerializer(question, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)   

    def delete(self, request, id):
        question = get_object_or_404(Question, pk=id) 
        question.delete()
        return Response(status=status.HTTP_204_NO_CONTENT) # ๋ฐ์ดํ„ฐ๊ฐ€ ์ž˜ ์ง€์›Œ์ง 204

์•„๊นŒ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ํด๋ž˜์Šค๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๊ฐ Methods๋ฅผ ํ•จ์ˆ˜๋กœ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

If ๋ฌธ์œผ๋กœ ๋‚˜๋ˆ„์–ด ๊ตฌ๋ถ„ํ–ˆ๋˜ ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋ณด๊ธฐ์— ํŽธํ•œ ๊ฒƒ ๊ฐ™๋‹ค!

๋‘ ์ฝ”๋“œ๋ฅผ ๋น„๊ตํ•ด๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, ๋ฐฉ์‹์ด ๋‹ค๋ฅผ ๋ฟ์ด์ง€ ์ฝ”๋“œ ์ž์ฒด๋Š” ๊ฑฐ์˜ ๋น„์Šทํ•˜๋‹ค.

 

ํ•˜์ง€๋งŒ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, urls.py์˜ path๋ฅผ ์ˆ˜์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

urlpatterns = [
    path('question/', QuestionList.as_view(), name='question-list'),
    path('question/<int:id>/', QuestionDetail.as_view(), name='question-detail'),
]

ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ, <ํด๋ž˜์Šค์ด๋ฆ„>.as_view() ์˜ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค!

 


Generics, mixins

 

๋ฐฉ๊ธˆ ๊ฒƒ๋ณด๋‹ค ๋” ์‰ฌ์šด ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

์ด์ œ๋Š” APIView๊ฐ€ ์•„๋‹Œ, generics์™€ mixins๋ผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework import mixins, generics

class QuestionList(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

class QuestionDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin,generics.GenericAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

์•„๊นŒ๋ณด๋‹ค ๋” ๊ฐ„๊ฒฐํ•ด์ง„๊ฒŒ ๋ˆˆ์— ๋ณด์ธ๋‹ค!

์ด ๋ถ€๋ถ„์€ ์ƒ์†๊ณผ ๊ฐ methods์˜ ์ธ์ž๋งŒ ์ฃผ์˜ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

  • .ListModelMixin : Queryset์„ Listingํ•˜๋Š” ๋ฏน์Šค์ธ, ๋ฐ์ดํ„ฐ๋ฅผ ๋ชฉ๋ก ๋ฆฌํ„ดํ•œ๋‹ค.
  • .CreateModelMixin : ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ €์žฅํ•œ๋‹ค.
  • .RetrieveModelMixin : ์กด์žฌํ•˜๋Š” ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค(ํ•˜๋‚˜)
  • .UpdateModelMixin : ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค.
  • .DestroyModelMixin : ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ญ์ œํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๊ฑธ ๊ธฐ์–ต์•ˆํ•ด๋„ ๋ ๋งŒํผ ๋” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค..

 


 

Generic API View

from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework import generics

class QuestionList(generics.ListCreateAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

class QuestionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

generics๊ฐ€ ์ง€์›ํ•˜๋Š” API view๋ฅผ ์ƒ์†๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋ฉด, ํ•จ์ˆ˜๊ณ  ๋ญ๊ณ  ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

queryset์— ํ•„์š”ํ•œ ๋ชจ๋ธ์˜ ๊ฐ์ฒด๋“ค๊ณผ Serializer๋งŒ ์ž˜ ๊ตฌํ˜„ํ•˜์—ฌ ์ž…๋ ฅํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

์–˜๋„ค๋“ค๋„ ์ƒ์†๋ฐ›์€ APIView์— ๋”ฐ๋ผ ์ง€์›ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ๋‹ค๋ฅธ๋ฐ, ์ด๊ฑด ์ด๋ฆ„์„ ์ž˜ ํ™•์ธํ•˜๋ฉด ๊ธฐ๋Šฅ์„ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

Ctrl + ํด๋ฆญ์œผ๋กœ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ๋ˆ„๋ฅด๋ฉด generics.py๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ํ•„์š”ํ•œ ํด๋ž˜์Šค๋ฅผ ์ฐพ์•„ ์ƒ์†์‹œ์ผœ์ฃผ๋ฉด ๋œ๋‹ค!

 


๐Ÿค” ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์–ด๋ ค์› ๋˜ ๋‚ด์šฉ

์†”์งํžˆ Serializer๊ฐ€ ์–ด๋–ค ๊ธฐ๋Šฅ์„ ํ•˜๋Š”์ง€ ์ •๋ง ์•Œ๊ธฐ ์–ด๋ ค์› ๋‹ค.

์—ฌ๋Ÿฌ ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐพ์•„๋ณด๋ฉฐ ๋Œ€์ถฉ ์ดํ•ดํ•œ ๊ฒƒ ๊ฐ™๊ธดํ•œ๋ฐ.. ๋ˆ„๊ฐ€ ๋ฌผ์–ด๋ณด๋ฉด ์ž์‹ ์žˆ๊ฒŒ ๋Œ€๋‹ต์€ ๋ชปํ•  ๊ฒƒ ๊ฐ™๋‹คใ…‹ใ…‹ใ…‹๐Ÿ˜‚

'TIL' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[TIL]KDT_20230428  (0) 2023.04.28
[TIL]KDT_20230427  (0) 2023.04.27
[TIL]KDT_20230425  (0) 2023.04.25
[TIL]KDT_20230424  (0) 2023.04.24
[TIL]KDT_20230421  (0) 2023.04.21