특징 비교
Form/ModelForm
- HTML 입력폼을 통한 입력에 대한 유효성 검사
- 주로 Create/Update에 대한 처리에서 활용
- 장고 admin 커스텀 할 때 활용
- CreateView/UpdateView CBV를 통한 뷰 처리 → 단일 뷰
Serializer/ModelSerializer
- Serializer는 뷰 응답을 생성하는 데 범용적이고 강력한 방법 제공
- ModelSerializer는 Serializer 생성을 위한 Shortcut
- 데이터 변환 및 직렬화 지원 ( ex. JSON 포맷 )
- Web API 포맷 (주로 JSON 포맷) 입력에 대한 유효성 검사
- List/Create 및 특정 Record에 대한 Retrieve/Edit/Delete 등 에서 활용
- APIView를 통한 뷰 처리 → 단일 뷰
- ViewSet을 통한 뷰 처리 → 2개 뷰 → 2개 URL 처리
주된 호출 주체
Form
- 일반적으로 웹 브라우저 상에서
- HTML Form Submit을 통해 POST 요청 받음
- JavaScript에 의한 비동기 호출
- Android/ios 앱에 의한 요청,응답도 가능 ← http(s) 프로토콜 요청, 응답이기 때문에
Serializer
- 다양한 Client (Web/Android/ios 등)에 대한 Data 위주의 http(s) 요청
- API 에 적합한 여러 기능들을 DRF에서 구현해주고 있고 Serializer가 그런 기능들과 잘 연계가 되어있다
클래스 정의
Form/ModelForm
from django import forms
class PostForm(forms.Form):
email = forms.EmailField()
content = forms.CharField(widget=forms.Textarea)
created_at = forms.DateTimeField()
class PostModelForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
Serializer/ModelSerializer
from rest_framework import serializers
class PostSerializers(serializers.Serializer):
email = forms.EmailField()
content = forms.CharField(max_length=200) #위젯같은 것은 없음
created_at = forms.DateTimeField()
class PostModelSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
FBV를 통한 요청/응답
Form/ModelForm
def post_list_or_create(request):
# create 구현
if request.method == 'POST':
form = PostForm(request.POST, request.FILES)
if form.is_valid():
post = form.save()
# 커스텀 직렬화 루틴 필요
return JsonResponse(post)
return JsonResponse(form.errors)
# list 구현
else:
qs = Post.objects.all()
# 커스텀 직렬화 루틴 필요
return JsonResponse(qs)
Serializer/ModelSerializer
def post_list_or_create(request):
# create 구현
if request.method == 'POST':
serializer = PostSerializer(data=request.POST)
if serializer.is_valid():
serializer.save()
reutrn Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
# list 구현
else:
qs = Post.objects.all()
serializer = PostSerializer(qs, many=True)
return Response(serializer.data)
CBV를 통한 요청/응답
Form/ModelForm
# views.py
from django.views.generic import ListView, CreateView
post_list = ListView.as_view(model=Post)
post_new = CreateView.as_view(model=Post, form_class=PostModelForm)
# urls.py
urlpatterns = [
path('', post_list),
path('new/'. post_new),
]
# templates
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit"/>
</form>
Serializer/ModelSerializer
from rest_framework.generics import ListCreateAPIView
class PostListCreateAPIView(ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostModelSerializer
post_list_create = PostListCreateAPIView.as_view()
urlpatterns = [
path('api/post/', post_list_create),
]
커스텀 유효성 검사 루틴
Form/ModelForm
clean_* 형식
from django import forms
class PostForm(forms.Form):
title = forms.CharField()
def clean_title(self):
value = self.cleand_data.get('title', '')
if 'django' not in value:
raise forms.ValidationError('제목에 django 포함돼야 함')
return value
Serializer/ModelSerializer
validate_* 형식
from rest_framework.exceptions import ValidationError
class PostSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
def validate_title(self, value):
if 'django' not in value:
raise ValidationError('제목에 django 포함돼야 함')
return value
※ 위와 아래의 ValidationError는 다른 것