Study Anything ๐Ÿง

[Django] DRF : Serializer ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•, ์œ ํšจ์„ฑ ๊ฒ€์ฆ ๋ณธ๋ฌธ

์Šคํ„ฐ๋””/Web

[Django] DRF : Serializer ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•, ์œ ํšจ์„ฑ ๊ฒ€์ฆ

์†” 2022. 1. 30. 23:28

์ฐธ๊ณ  : https://www.django-rest-framework.org/api-guide/serializers/

 

 

์žฅ๊ณ  ๋ ˆ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ(Django REST Framework)๋ฅผ ์ด์šฉํ•ด REST API ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•˜๋‹ค๋ณด๋ฉด

Serializer๋ฅผ ๊ฑฐ์˜ ํ•„์ˆ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

ํ•˜์ง€๋งŒ Serializer๊ฐ€ ์–ด๋–ค ๊ฐœ๋…์ธ์ง€ ์ž˜ ์™€๋‹ฟ์ง€ ์•Š์•„์„œ Serializer์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•˜๊ณ  ์•Œ๊ฒŒ ๋œ ๊ฒƒ๋“ค์„ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

 

 

 

(1) Serializer๋ž€?

 

์ฟผ๋ฆฌ์…‹์ด๋‚˜ ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค ๊ฐ™์€ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ๋“ค์„ ๋„ค์ดํ‹ฐ๋ธŒ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ

json, xml ๋“ฑ์˜ ์ปจํ…์ธ  ํƒ€์ž…์œผ๋กœ ์‰ฝ๊ฒŒ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ ์ง๋ ฌํ™”ํ•˜๋Š” Serializer๋Š” ์—ญ์ง๋ ฌํ™” ๊ธฐ๋Šฅ ๋˜ํ•œ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์—

๋“ค์–ด์˜ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ฆํ•œ ํ›„์— ๋ถ„์„๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์žกํ•œ ํ˜•์‹์œผ๋กœ ๋‹ค์‹œ ๋ณ€ํ™˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

REST Framework์˜ Serializer๋Š” ์žฅ๊ณ ์˜ Form, ModelForm ํด๋ž˜์Šค์™€ ๋งค์šฐ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•œ๋‹ค.

DRF๊ฐ€ ์ œ๊ณตํ•˜๋Š” Serializer ํด๋ž˜์Šค๋Š” ์‘๋‹ต์˜ ์ถœ๋ ฅ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ณ ,

ModelSerializer๋Š” ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค ๋ฐ ์ฟผ๋ฆฌ ์ง‘ํ•ฉ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ง๋ ฌํ™” ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

 

 

 

 

(2) Serializer ์„ ์–ธํ•˜๊ณ  ๋ชจ๋ธ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ํ•˜๊ธฐ

 

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ชจ๋ธ์„ ์„ ์–ธํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.

(์˜ˆ์‹œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์ฝ”๋“œ์˜ ์ถœ์ฒ˜๋Š” ๊ณต์‹ ์‚ฌ์ดํŠธ์ด๋‹ค.)

# models.py
from datetime import datetime

class Comment:
    def __init__(self, email, content, created=None):
        self.email = email
        self.content = content
        self.created = created or datetime.now()

comment = Comment(email='leila@example.com', content='foo bar')

๋‹ค์Œ์œผ๋กœ๋Š” ํ•ด๋‹น ๋ชจ๋ธ์„ ์ง๋ ฌํ™”ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Serializer๋ฅผ ์„ ์–ธํ•œ๋‹ค.

# serializer.py
from rest_framework import serializers

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

 

 

์ด์ œ CommentSerializer(์ดํ•˜ CS)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Comment ๊ฐ์ฒด์™€ Comment ๋ฆฌ์ŠคํŠธ๋ฅผ ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

serializer = CommentSerializer(comment)
serializer.data
# ๋ฐ์ดํ„ฐ๊ฐ€ ๋”•์…”๋„ˆ๋ฆฌ ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค๋ฅผ ํŒŒ์ด์ฌ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฐ์ดํ„ฐ ์œ ํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ–ˆ๋‹ค.

์ง๋ ฌํ™” ํ”„๋กœ์„ธ์Šค๋ฅผ ๋งˆ๋ฌด๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ json์œผ๋กœ ๋ Œ๋”๋งํ•œ๋‹ค.

from rest_framework.renderers import JSONRenderer

json = JSONRenderer().render(serializer.data)
json
# b'{"email":"leila@example.com","content":"foo bar","created":"2016-01-27T15:17:10.375877"}'

 


์—ญ์ง๋ ฌํ™”๋„ ๋น„์Šทํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋จผ์ €, stream์„ ํŒŒ์ด์ฌ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๊ตฌ๋ฌธ ๋ถ„์„ํ•œ๋‹ค.

import io
from rest_framework.parsers import JSONParser

stream = io.BytesIO(json)
data = JSONParser().parse(stream)

 

๋‹ค์Œ์œผ๋กœ, ์ด๋Ÿฐ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ๊ฒ€์ฆ๋œ ๋ฐ์ดํ„ฐ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

serializer = CommentSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# ๋ฐ์ดํ„ฐ๊ฐ€ ๋”•์…”๋„ˆ๋ฆฌ ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜๋จ

 

 

 

(3) ์ธ์Šคํ„ด์Šค ์ €์žฅํ•˜๊ธฐ

๊ฒ€์ฆ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์™„์ „ํ•œ ๊ฐœ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด

create() ๋ฐ update() ๋ฉ”์†Œ๋“œ๋ฅผ ํ•˜๋‚˜ ๋˜๋Š” ๋‘˜ ๋‹ค ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

# serializer.py
class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

    def create(self, validated_data):
        return Comment(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        return instance

๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๊ฐ€ Django ๋ชจ๋ธ๊ณผ ์ผ์น˜ํ•  ๊ฒฝ์šฐ, ๊ตฌํ˜„ํ•œ ๋ฉ”์†Œ๋“œ๊ฐ€ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

# serializer.py
def create(self, validated_data):
	return Comment.objects.create(**validated_data)

def update(self, instance, validated_data):
	instance.email = validated_data.get('email', instance.email)
	instance.content = validated_data.get('content', instance.content)
	instance.created = validated_data.get('created', instance.created)
	instance.save()
	return instance

์ด ๊ณผ์ •์„ ๊ฑฐ์น˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ save() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(๋‹จ, ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฒ€์ฆ๋œ ์ƒํƒœ์ผ ๋•Œ)

save() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Serializer ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™” ํ•  ๋•Œ ๊ธฐ์กด ์ธ์Šคํ„ด์Šค๊ฐ€ ์ „๋‹ฌ๋œ ๊ฒƒ์ธ์ง€์˜ ์—ฌ๋ถ€์— ๋”ฐ๋ผ

์ƒˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜ ๊ธฐ์กด ์ธ์Šคํ„ด์Šค๊ฐ€ ์—…๋ฐ์ดํŠธ๋œ๋‹ค.

comment = serializer.save()

# ๊ธฐ์กด์— ์—†๋Š” ์ธ์Šคํ„ด์Šค์ผ ๋•Œ: save() will create a new instance.
serializer = CommentSerializer(data=data)

# ๊ธฐ์กด์— ์žˆ๋Š” ์ธ์Šคํ„ด์Šค์ผ ๋•Œ: save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)

๋‹ค๋งŒ create()์™€ update() ๋ฉ”์†Œ๋“œ๋Š” ์„ ํƒ์‚ฌํ•ญ์œผ๋กœ, Serializer ํด๋ž˜์Šค๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ์ง€์— ๋”ฐ๋ผ์„œ

ํ•˜๋‚˜ ๋˜๋Š” ๋‘˜ ๋‹ค ๊ตฌํ˜„ํ•  ์ˆ˜๋„, ๊ตฌํ˜„ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค.

 

 

save() ๋ฉ”์†Œ๋“œ์— ์ถ”๊ฐ€ ํŠน์„ฑ์„ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์ธ์Šคํ„ด์Šค๋ฅผ ์ €์žฅํ•  ๋•Œ ์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ์ด ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ์ดํ„ฐ์—๋Š” ํ˜„์žฌ ์‚ฌ์šฉ์ž, ํ˜„์žฌ ์‹œ๊ฐ„ ๋˜๋Š” ์š”์ฒญ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์ •๋ณด๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ ์ฝ”๋“œ์ฒ˜๋Ÿผ save() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ถ”๊ฐ€ ํ‚ค์›Œ๋“œ ์ธ์ˆ˜๋ฅผ ํฌํ•จํ•˜๋ฉด ๋œ๋‹ค.

์ถ”๊ฐ€ํ•œ ์ธ์ˆ˜๋Š” create() ๋˜๋Š” update() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ validated_data ์ธ์ˆ˜์— ํฌํ•จ๋œ๋‹ค.

(์œ„์— ์ž‘์„ฑํ•œ create, update ๋ฉ”์†Œ๋“œ ์ฐธ๊ณ )

serializer.save(owner=request.user)

 

 

๊ตฌํ˜„ํ•˜๋ ค๋Š” ๊ธฐ๋Šฅ์˜ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๋ฉ”์ผ์ด๋‚˜ ๋‹ค๋ฅธ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ๋“ฑ 

create()๋‚˜ update() ๋ฉ”์†Œ๋“œ์˜ ์ด๋ฆ„์ด ์˜๋ฏธ๊ฐ€ ์—†์„ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿด ๋• save() ๋ฉ”์†Œ๋“œ๋ฅผ ์ง์ ‘ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” Serializer์˜ validated_data ์†์„ฑ์— ์ง์ ‘ ์•ก์„ธ์Šคํ•ด์•ผ ํ•œ๋‹ค.

class ContactForm(serializers.Serializer):
    email = serializers.EmailField()
    message = serializers.CharField()

    def save(self):
        email = self.validated_data['email']
        message = self.validated_data['message']
        send_email(from=email, message=message)

 

 

 

(4) ์œ ํšจ์„ฑ ๊ฒ€์ฆํ•˜๊ธฐ (Validation)

 

๋ฐ์ดํ„ฐ๋ฅผ ์—ญ์งˆ๋ ฌํ™” ํ•  ๋•Œ, ๊ฒ€์ฆ๋œ ๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šคํ•˜๊ฑฐ๋‚˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ €์žฅํ•˜๊ธฐ ์ „์—๋Š” 

ํ•ญ์ƒ is_valid() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.
๋งŒ์•ฝ ๊ฒ€์ฆ ๊ณผ์ •์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด error ์†์„ฑ์— ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋”•์…”๋„ˆ๋ฆฌ๊ฐ€ ํฌํ•จ๋œ๋‹ค. (์ €์žฅ๋œ๋‹ค.)
๋”•์…”๋„ˆ๋ฆฌ์˜ ๊ฐ ํ‚ค๋Š” ํ•„๋“œ ์ด๋ฆ„์ด ๋˜๊ณ , ๊ทธ ๊ฐ’์€ ํ•ด๋‹นํ•˜๋Š” ํ•„๋“œ์— ํ•ด๋‹นํ•˜๋Š” ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€๊ฐ€ ๋œ๋‹ค. 

non_field_errors ํ‚ค๋„ ์žˆ์„ ์ˆ˜ ์žˆ๊ณ , ์ด ๊ฒฝ์šฐ๋Š” ์ผ๋ฐ˜์ ์ธ ๊ฒ€์ฆ ์˜ค๋ฅ˜ ๋ชฉ๋ก์ด ๋œ๋‹ค.
๊ฐ์ฒด ๋ฆฌ์ŠคํŠธ๋ฅผ ์—ญ์ง๋ ฌํ™” ํ•  ๋•Œ, ์˜ค๋ฅ˜๋Š” ๊ฐ ํ•ญ๋ชฉ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋”•์…”๋„ˆ๋ฆฌ ๋ชฉ๋ก์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.

serializer = CommentSerializer(data={'email': 'foobar', 'content': 'baz'})
serializer.is_valid()
# False
serializer.errors
# {'email': ['Enter a valid e-mail address.'], 'created': ['This field is required.']}

 

 

๋˜ํ•œ is_valid() ๋ฉ”์†Œ๋“œ๋Š” raise_exception ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒ€์ฆ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ

serializers.ValidationError ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
์ด๋Ÿฐ ์˜ˆ์™ธ๋“ค์€ HTTP 400 ๋ฐ˜์‘์„ ๋ฐ˜ํ™˜ํ•˜๋Š” REST ํ”„๋ ˆ์ž„์›Œํฌ ์ œ๊ณต์˜ ๊ธฐ๋ณธ ์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค.

# ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฒ€์ฆ๋˜์ง€ ์•Š์œผ๋ฉด 400 ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
serializer.is_valid(raise_exception=True)

 

 

Serializer ํ•˜์œ„ ํด๋ž˜์Šค์— validate_<field_name>() ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ 

์‚ฌ์šฉ์ž ์ง€์ •์˜ ํ•„๋“œ ์ˆ˜์ค€ ๊ฒ€์ฆ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. 

์ด๋Š” ์žฅ๊ณ  Form์˜ clean_[field_name]() ๋ฉ”์†Œ๋“œ์™€๋„ ๋น„์Šทํ•˜๋ฉฐ, 

๊ฒ€์ฆ์ด ํ•„์š”ํ•œ ํ•„๋“œ ๊ฐ’๋ฅผ ์ธ์ˆ˜๋กœ ํ•˜๋Š” ๋‹จ์ผ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์ด ๋ฉ”์†Œ๋“œ๋Š” ๊ฒ€์ฆ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ serializers.ValidationError๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์•ผ ํ•œ๋‹ค.

from rest_framework import serializers

class BlogPostSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=100)
    content = serializers.CharField()

    def validate_title(self, value):
        """
        Check that the blog post is about Django.
        """
        if 'django' not in value.lower():
            raise serializers.ValidationError("Blog post is not about Django")
        return value

 

 

์—ฌ๋Ÿฌ ํ•„๋“œ์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•˜๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด ์ˆ˜์ค€์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ

Serializer ํ•˜์œ„ ํด๋ž˜์Šค์— validate() ๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. 
์ด ๋ฉ”์†Œ๋“œ๋Š” ํ•„๋“œ ๊ฐ’์˜ ๋”•์…”๋„ˆ๋ฆฌ ์ธ์ˆ˜๋ฅผ ๋‹จ์ผ๋กœ ์‚ฌ์šฉํ•˜๋ฉฐ,

ํ•„๋“œ ์ˆ˜์ค€๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฒ€์ฆ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—” serializers.ValidationError๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์•ผ ํ•œ๋‹ค.

from rest_framework import serializers

class EventSerializer(serializers.Serializer):
    description = serializers.CharField(max_length=100)
    start = serializers.DateTimeField()
    finish = serializers.DateTimeField()

    def validate(self, data):
        """
        Check that start is before finish.
        """
        if data['start'] > data['finish']:
            raise serializers.ValidationError("finish must occur after start")
        return data

 

 

Serializer์˜ ๊ฐœ๋ณ„ ํ•„๋“œ๋Š” ํ•„๋“œ ์ธ์Šคํ„ด์Šค์— ์„ ์–ธํ•˜์—ฌ ๊ฒ€์ฆ์ž(Validator)๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค. 

def multiple_of_ten(value):
    if value % 10 != 0:
        raise serializers.ValidationError('Not a multiple of ten')

class GameRecord(serializers.Serializer):
    score = IntegerField(validators=[multiple_of_ten])
    ...

Serializer ํด๋ž˜์Šค์—๋Š” ์ „์ฒด ํ•„๋“œ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์— ์ ์šฉ๋˜๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒ€์ฆ์ž๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ,

์ด๋Ÿฐ ๊ฒ€์ฆ์ž๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚ด๋ถ€ ๋ฉ”ํƒ€ ํด๋ž˜์Šค์— ์„ ์–ธํ•จ์œผ๋กœ์จ ํฌํ•จ๋œ๋‹ค.

class EventSerializer(serializers.Serializer):
    name = serializers.CharField()
    room_number = serializers.IntegerField(choices=[101, 102, 103, 201])
    date = serializers.DateField()

    class Meta:
        # Each room only has one event per day.
        validators = [
            UniqueTogetherValidator(
                queryset=Event.objects.all(),
                fields=['room_number', 'date']
            )
        ]

 

 

 

์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” Serializer์˜ ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ๋ฒ•๊ณผ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์•˜๋‹ค.

๋” ์ž์„ธํ•˜๊ณ  ๋‹ค์–‘ํ•œ ๋‚ด์šฉ๋“ค์ด ๋งŽ์ง€๋งŒ, ๊ธฐ๋ณธ์ ์œผ๋กœ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐœ๋…์€ ์ด ์ •๋„์ธ ๊ฒƒ ๊ฐ™๋‹ค.

์˜ค๋Š˜ ์Šคํ„ฐ๋”” ํ•œ ๋‚ด์šฉ๋“ค์„ ๋ฐ”ํƒ•์œผ๋กœ ํ”„๋กœ์ ํŠธ์—์„œ Serializer๋ฅผ ์ž˜ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

 

 

 

 

728x90
Comments