일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 숫자 형식
- 웹브라우저 수용도
- 생성자
- 배열 예제
- SQL입문
- 자바
- HTML역사
- Doit입문SQL
- R1C3
- 함수
- 자바 예외
- 함수 선언
- SQL
- 웹 브라우저 전쟁
- 크롤링
- 데이터베이스
- 자바 오류
- 예외
- 예제
- DoIt
- DoitSQL
- 페이지분석
- 우아한테크
- html
- DoitSQL입문
- 숫자형식오류
- dbms
- 크롤링 오류
- 키-값 데이터베이스
- 배열 3요소
- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 숫자 형식
- 웹브라우저 수용도
- 생성자
- 배열 예제
- SQL입문
- 자바
- HTML역사
- Doit입문SQL
- R1C3
- 함수
- 자바 예외
- 함수 선언
- SQL
- 웹 브라우저 전쟁
- 크롤링
- 데이터베이스
- 자바 오류
- 예외
- 예제
- DoIt
- DoitSQL
- 페이지분석
- 우아한테크
- html
- DoitSQL입문
- 숫자형식오류
- dbms
- 크롤링 오류
- 키-값 데이터베이스
- 배열 3요소
- Today
- Total
프로그래밍
[DRF] View / Model / Serializer 각각 어디까지 처리하는 것이 이상적인가? 본문
[DRF] View / Model / Serializer 각각 어디까지 처리하는 것이 이상적인가?
시케 2024. 12. 16. 17:542024.12.16.월
Django 프레임워크에서의 역할 분담
Django 프레임워크를 사용하면 여느 프레임워크처럼 각각 역할이 있다
로직을 처리하는 곳은 목적성과 유지보수성과 같은 것에 따라 사용자가 어느정도 분리하는 것도 있지만
프레임워크는 기본적으로 구조를 강제한다
Django의 구조와 역할 분담이 어떻게 되어있는지 알고 로직을 작성하는 것은 중요하다
View
view는 기본적으로 비즈니스 로직을 수행하는 곳이다
즉, 사용자(client)의 요청과 응답을 처리한다
요청을 받고 필요하다면 여타 Model등을 호출하여 사용하며 알맞는 응답을 반환한다
Serializer와 Model을 사용하는 주체는 View이다
주요 역할
- HTTP 요청 처리 (GET, POST, PUT, DELETE)
- Serializer를 통해 데이터 직렬화/역직렬화
- 비즈니스 로직이 필요한 경우 Model 메서드를 호출
Model
Model은 데이터베이스와 관련된 모든 것을 담당한다
Django는 강력한 ORM 기능을 가지고 있다
데이터를 정의하고 그에 따른 CRUD를 처리한다
주요 역할
- 데이터 구조 정의 (fields)
- 데이터 저장, 수정, 삭제 (CRUD)
- 데이터 관련 비즈니스 로직 (메서드 추가)
Serializer
Model의 데이터를 JSON 등으로 변환하거나, 입력된 데이터를 검증하는 역할을 한다
Model에 정의되어 있는 내용을 바탕으로 유효한 데이터인지 아닌지 검증하며
View에서 사용자가 받기 좋은 형태로 바꿔주는 직렬화를 수행한다
(사용자가 보낸 데이터를 ORM에 맞는 객체로 바꾸는 것이 역직렬화이다)
주요 역할
- 데이터를 원하는 형태로 변환
- 입력된 데이터의 유효성 검사
- 필드 레벨에서의 추가적인 데이터 처리
로직의 의도와 성격
그럼 이쯤에서 의문점이 생길 수 있다
- 비즈니스 로직 자체는 View가 수행하는데 왜 Model에서도 수행 가능하다고 하는가?
- 유효성 검사는 Model 정의 자체로 가능한것 아닌가? 왜 Serializer에서 수행하는가?
View와 Model
비즈니스 로직 자체는 View가 수행하는데 왜 Model에서도 수행 가능하다고 하는가?
비즈니스 로직 자체는 View가 중심인 것이 맞다
하지만, 무조건 Model 특정필드가 저장될때 값을 변환하거나 자동으로 날짜 등을 입력하는 경우가 있다
이 경우 데이터와 관련된 비즈니스 로직이다
즉, 사용자의 요청을 중심으로 한 비즈니스 로직의 성질 보다는
데이터가 알맞게 변환되어야 하기 위해 추가되는 로직에 가깝다
해당 경우에는 Model에서 별도의 메서드 혹은 save 메서드에 추가하여 실행하도록 한다
View는 사용자의 요청(Request)을 중심으로 한 비즈니스 로직을 처리
→ 데이터 생성 전 추가 검증, 외부 API 호출, 복합적인 처리
Model은 데이터의 무결성과 일관성을 유지하기 위해 필요한 로직을 처리
→ 필드 값 변환, 자동 시간 설정, 데이터 유효성 검사
"데이터 무결성과 관련된 로직"은 모델에 두고,
"사용자의 요청에 따른 흐름 제어"는 뷰에 두는 것이 적절하다
models.py
from django.db import models
from django.utils import timezone
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
discount = models.FloatField(default=0.0)
created_at = models.DateTimeField(auto_now_add=True) # 생성 시 자동으로 현재 시간 저장
updated_at = models.DateTimeField() # 수동으로 업데이트
def save(self, *args, **kwargs):
# 비즈니스 로직: 가격이 음수면 예외 발생
if self.price < 0:
raise ValueError("Price cannot be negative.")
# 비즈니스 로직: 할인된 가격 계산
self.price = self.price * (1 - self.discount)
# updated_at을 현재 시간으로 업데이트
self.updated_at = timezone.now()
super().save(*args, **kwargs)
def get_discounted_price(self):
return self.price * (1 - self.discount)
views.py
# 예제 데이터 생성
product = Product(name="Sample Product", price=1000, discount=0.1)
product.save()
print(product.created_at) # 생성된 시간 출력
print(product.updated_at) # 저장될 때의 현재 시간 출력
# 데이터 수정
product.price = 1200
product.save()
print(product.updated_at) # 수정된 시간으로 갱신됨
Model과 Serializer
유효성 검사는 Model 정의 자체로 가능한것 아닌가? 왜 Serializer에서 수행하는가?
먼저 Model에 정의되어 있기 때문에 검증하지 않고 Model에 넘겨버리는 것은
기본 역할 자체를 떠넘기는 행위이다
이는 View에서도 Model에서 알아서 저장되지 않는 무결하지 않은 데이터를 넘기는 것도 해당한다
Front-end는 유효하지 않은 데이터를 Back-end로 전달하면 안되며
Back-end는 무결하지 않은 혹은 CRUD를 수행하지 않을 데이터를 Model로 전달하면 안된다
Model은 기본적인 로직 처리는 가능하지만 "유효성 검사"를 처리하도록 하면 안된다
Serializer의 목적성은 client와 server 간의 데이터 송수신시 데이터를 알맞게 변환(직렬화/역직렬화)하고
Model에 보내도 되는 데이터인지 검증한다
또한 비즈니스 로직마다 수행해야 하는 유효성 검사가 다르거나 특정필드의 포함 유무가 다를 수 있기도 하다
Model: 데이터베이스와 관련된 기본적인 유효성 검사를 처리
Serializer: 클라이언트 요청 데이터를 변환하고 비즈니스 로직에 맞는 유효성 검사를 수행
View: Serializer를 사용해 데이터를 검증하고, 유효한 데이터만 Model에 저장
Model은 데이터베이스 저장과 관련된 기본적인 유효성 검사(예: 필드 타입, 필수 값)를 처리하지만,
비즈니스 로직이나 요청 상황에 따른 유효성 검사는 수행하지 않는다
Serializer가 요청 데이터를 검증하고, Model에 유효한 데이터만 넘긴다
특정 비즈니스 로직에 따라 유효성 검사 조건이 달라질 수 있으므로,
View와 API 레이어에서 검증을 추가하는 것이 효율적이다
models.py
from django.db import models
class UserProfile(models.Model):
name = models.CharField(max_length=50) # 필수 입력
age = models.IntegerField() # 나이: 양수여야 함
created_at = models.DateTimeField(auto_now_add=True) # 생성 날짜 자동 저장
def __str__(self):
return self.name
serializers.py
from rest_framework import serializers
from .models import UserProfile
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ['name', 'age', 'created_at']
# 추가 유효성 검사: 나이는 0보다 커야 함
def validate_age(self, value):
if value <= 0:
raise serializers.ValidationError("나이는 0보다 커야 합니다.")
return value
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import UserProfile
from .serializers import UserProfileSerializer
class UserProfileView(APIView):
def post(self, request):
serializer = UserProfileSerializer(data=request.data)
# 유효성 검사 수행
if serializer.is_valid():
serializer.save() # 검증 통과 후 Model에 저장
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
'Python > Django REST Framework' 카테고리의 다른 글
[DRF] From Data로 Boolean 타입 받기(feat. Serializer) (0) | 2024.12.18 |
---|---|
[DRF] QueryDict과 Class Dict(feat. HTTP 메서드) (0) | 2024.12.18 |
[DRF] status (0) | 2023.11.29 |
[DRF] Response (0) | 2023.11.29 |
[DRF] APIView와 api_view (1) | 2023.11.29 |