이후에 views에서 return super가 나오게 되면 자동적으로 absolute_url 이 실행
/photo/models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
# Create your models here.
class Photo(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user')
#장고에서 구현하는 user 불러와 photo를 fk로 연결
text = models.TextField(blank=True)
image = models.ImageField(upload_to = 'timeline_photo/%Y/%m/%d')
#timeline_photo 폴더에 연, 월, 일 만들어 사진 저장
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return "text : " + self.text
#admin 사이트 화면 표시 구현
class Meta:
ordering = ['-created']
#ordering 정렬
def get_absolute_url(self):
return reverse('photo:detail', args = [self.id])
#상세페이지로 이동하도록 absolute_url 설정, views 에서 return super가 나오게되면 absolute가 실행
from django.shortcuts import render
from django.views.generic.list import ListView
from django.views.generic.edit import UpdateView, CreateView, DeleteView
from django.views.generic.detail import DetailView
from .models import Photo
# class형 뷰의 generic view를 이용하여 구현
# ListView/CreateView/UpdateView/DeleteView/DetailView 구현
class PhotoList(ListView):
model = Photo
template_name_suffix = '_list'
#PhotoList:가장 메인에서 보여줄 로직 / 모델을 불러와서 데이터를 활용할 것이라고 기제
class PhotoCreate(CreateView):
model = Photo
fields = ['text', 'image']
template_name_suffix = '_create'
success_url = '/'
# PhotoCreate:
# 모델을 활용하는데생성할 때 채워야 할 필드 확인이후 연결될 템플릿 이름은 Photo_create 일 것이다.
#성공하면 메인 페이지로 돌아가도록 연결(이후 url로 연결)
class PhotoUpdate(UpdateView):
model = Photo
fields = ['text', 'image']
template_name_suffix = '_update'
success_url = '/'
#photoUpdate : Create와 동일
class PhotoDelete(DeleteView):
model = Photo
template_name_suffix = '_delete'
success_url = '/'
class PhotoDetail(DetailView):
model = Photo
template_name_suffix = '_detail'
#PhotoDelete와 PhotoDetail
#삭제와 상세페이지는 특별한 로직이 필요하지 않음
#템플릿과 연결을 잘 시킬 수 있도록
<URL 연결하기>
- Photo URL 연결하기
photo의 urls.py 생성 ( instagram/photo/urls.py)
URL 작성하기
from django.urls import path
from .views import PhotoList, PhotoDelete, PhotoDetail, PhotoUpdate, PhotoCreate
app_name = "photo"
#app_name 설정을 통해 namespace(이름공간)확보
#다른 앱들과 url pattern 이름이 겹치는 것을 방지하기 위해 사용한다.
urlpatterns = [
path("create/", PhotoCreate.as_view(), name = 'create'),
path("delete/<int:pk>/", PhotoDelete.as_view(), name = 'delete'),
path("update/<int:pk>/", PhotoUpdate.as_view(), name = 'update'),
path("detail/<int:pk>/", PhotoDetail.as_view(), name = 'detail'),
path("", PhotoList.as_view(), name = 'index'),
]
- Config URL 연결하기
config의 url.py에 작성(instagram/config/urls.py)
2차 URL을 설정한 이후에 가장 기본이 되는 URL과 연결시켜준다.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('photo.urls')),
]
-> 사용자가 게시판의 전체 글 목록 요청 시 / 수 많은 데이터들을 한번에 전달 한다면 데이터를 받는 사용자는 많은 데이터를 감당할 수 없을 것
API 서버에서 Pagination을 사용하는 이유
- > 하나의 Request 만으로 처리하기 어려운 레코드들을 여러 Request로 나누어 전송하기 위해 사용
DRF에서의 Pagination
PageNumberPagination
LimitOffsetPagination
CursorPagination
CustomizedPagination
1, 2, 3 = Django restFramework 에서 제공하는 Pagination class
4 = 직접 Pagination class를 직접 커스터마이징 해서 사용하는 방법
흔히, PageNumberPagination 을 Default로 설정하고
추가적인 페이지 설정 부분만 CustomizedPagination 을 사용
프로젝트 기본 세팅
1. Django Project 생성
2. 경로 이동 및 앱 생성
3. settings.py에 앱 등록
4. models.py 작성 및 admin.py 연결
5. makemigrations 및 migrate 진행
6. serializer.py 생성 및 작성
from .models import Post
from rest_framework import serializers
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = "__all__"
7. views.py 작성
from .models import Post
from .serializer import PostSerializer
from rest_framework import viewsets
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
8. urls.py 작성
- 앱 내부의 urls.py
from rest_framework.routers import DefaultRouter
from django.urls import include, path
from .views import PostViewSet
router = DefaultRouter()
router.register('post', PostViewSet)
urlpatterns = [
path('', include(router.urls))
]
- 프로젝트 폴더의 urls.py
from django.contrib import admin
from django.urls import path, include
import post.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(post.urls)),
]
DRF로 Pagination 구현하기
DEFAULT_PAGINATION_CLASS는 None이며 PAGE_SIZE 또한 NONE이다.
settings.py에 Pagination관련 설정하기
- DEFAULT_PAGINATION_CLASS에 Pagination 클래스를 설정하고, PAGE_SIZE에 한 번에 가져올 레코드의 수 설정
아래와 같이 한 번에 10개씩의 레코드만 가져오는 것을 확인할 수 있다. 총 데이터의 개수인 count와 이전 10개의 레코드 주소인 previous 다음 10개의 레코드를 위한 next또한 RESPONSE에 생겼다.
유의 사항
Pagination을 사용할 때는 반드시 레코드를정렬해 사용해야 한다. => views.py를 아래와 같이id로정렬하도록 수정해준다.
from .models import Post
from .serializer import PostSerializer
from rest_framework import viewsets
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all().order_by('id')
serializer_class = PostSerializer
CustomizedPagination 클래스 작성하기
PageNumberPagination을 상속받는 클래스를 선언하고 클래스 내부에page_size변수에 원하는 레코드의 수를 지정한 후 적용할 모델의ViewSet의pagination_class에 클래스를 지정하면 된다.
...
from rest_framework.pagination import PageNumberPagination
class MyPagination(PageNumberPagination):
page_size = 6
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all().order_by('id')
serializer_class = PostSerializer
pagination_class = MyPagination
코드 클린
1. pagination.py생성 및 클래스 옮기기
from rest_framework.pagination import PageNumberPagination
class MyPagination(PageNumberPagination):
page_size = 6
2. views.py 에 추가, 사용
from .models import Post
from .serializer import PostSerializer
from .pagination import MyPagination
from rest_framework import viewsets
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all().order_by('id')
serializer_class = PostSerializer
pagination_class = MyPagination
class Photo(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user')
#장고에서 구현하는 user 불러와 photo를 fk로 연결
text = models.TextField(blank=True)
image = models.ImageField(upload_to = 'timeline_photo/%Y/%m/%d')
#timeline_photo 폴더에 연, 월, 일 만들어 사진 저장
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return "text : " + self.text
#admin 사이트 화면 표시 구현
class Meta:
ordering = ['-created']
#ordering 정렬
-settings.py 에서 media 루트 설정 (/instagram/config/settings.py)
STATIC_URL = '/static/'
MEDIA_URL = '/res/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
#MEDIA_URL 을 설정하고 ROOT를 잡아주어서 저기로 사진이 저장되도록 한다.
-모델 설계 이후 migration
Image파일을 업로드 하기 위해 pip install Pillow를 해줘야 한다.
pip install Pillow
python manage.py makemigrations photo
python manage.py migrate
-admin site 등록(/instagram/photo/admin.py)
from django.contrib import admin
from .models import Photo
# Register your models here.
admin.site.register(Photo)
- 확인해보기
$ python manage.py createsuperuser
Username (leave blank to use 'user'): admin
Email address: 282532@naver.com
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
from rest_framework import viewsets
from .models import Post
from .serializer import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class =
ViewSet
-> View(CRUD)를 설계하는 가장 간단한 방법
2. APIView
-> 장점 : 자신의 마음대로 코드를 작성할 수 있다.
-> 단점 : CBV의 장점인 중복되는 코드 제거를 하지 못한다.
-> Response : 클라이언트가 요청한 형태로 콘텐츠를 렌더링 해준다.
-> Status : Http 에서 제공하는 상태 코드는 숫자이지만, REST 프레임워크에서는 문자 형태의 식별자를 제공하여 상태를 좀더 잘 구분할 수 있도록 한다.
-> APIView를 상속해서 view를 설계할 때는 status 와 Response를 import 하여 Response과정을 작성
-> APIView를 상속해서 만든 CBV의 내부 함수들은 필요로 하는 HTTP Method 이름으로 갖는다.
-> 어떠한 status를 받고 response를 전달할지 직접 정하는 것이 apiview를 상속받은 cbv
class SnippetDetail(APIView):
def get(...):
...
def put(...):
...
def delete(...):
...
#SnippetDetail 클래스에 필요한 method는 GET, PUT, DELETE
##실습해보기
django-admin startproject <project-name>
cd <project-name>
python manage.py startapp <app-name>
settings.py에 App, rest_framework추가
models.py에 모델 작성 및 migrate
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
serializer.py 생성 및 작성
from .models import Post
from rest_framework import serializers
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = "__all__"
views.py 작성 1) 필요한 모듈 추가(apiview를 상속받은 cbv를 작성하기 위해 아래 모듈 추가)
from CBV.models import Post
from CBV.serializer import PostSerializer
from django.http import Http404
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
2)객체들 목록 가져오는 PostList 작성
- post 메서드는 다수의 post 객체를 반환하는 메서드
- 다수의 객체를 직렬화 하기위해서는 PostSerializer 에 many = True를 넘겨야 한다
- post 메서드는 새로운 객세 생성하는 함수
- 저장 성공시 상태코드 201(created) / 반환 실패시 400(bad request)반환
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
urlpatterns = [
path("post", views.PostList.as_view()),
path("post/<int:pk>", views.PostDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
- 프로젝트 폴더 내부의 urls.py 에 include
from django.contrib import admin
from django.urls import path, include
import post.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(post.urls)),
]
실행하고 http://127.0.0.1:8000/post 에 접속하면 정상 작동한다
4. Generic CBV
<분류>
기반 뷰(Base View): 뷰 클래스를 생성하고 다른, 제너릭 뷰의 부모 클래스가 되는 기본 제너릭 뷰
view : 최상위 부모 제너릭 뷰 클래스
TemplateView : 주어진 템플릿으로 렌더링
RedirectView : 주어진 URL로 리다이렉트
제너릭 보기 뷰(Generic Display View): 객체의 목록 또는 하나의 객체 상세 정보를 보여주는 뷰
DetailView : 조건에 맞는 하나의 객체 출력
ListView : 조건에 맞는 객체 목록 출력
제너릭 수정 뷰(Generic Edit View): 폼을 통해 객체를 생성, 수정, 삭제하는 기능을 제공하는 뷰
FormView : 폼이 주어지면 해당 폼 출력
CreateView : 객체 생성하는 폼 출력
UpdateView : 기존 객체 수정하는 폼 출력
DeleteView : 기존 객체 삭제하는 폼 출력
제너릭 날짜 뷰(Generic Date View): 날짜 기반 객체의 연/월/일 페이지로 구분해 보여주는 뷰
YearArchiveView : 주어진 연도에 해당하는 객체 출력
MonthArchiveView : 주어진 월에 해당하는 객체 출력
DayArchiveView : 주어진 날짜에 해당하는 객체 출력
TodayArchiveVIew : 오늘 날짜에 해당하는 객체 출력
DateDetailView : 주어진 연, 월, 일 PK(OR 슬러그)에 해당하는 객체 출력
<제너릭 뷰 오버라이딩>
속성 변수 오버라이딩
model : 기본 뷰(View, Template, RedirectView) 3개를 제외하고 모든 제너릭 뷰에서 사용한다.
queryset : 기본 뷰(View, Template, RedirectView) 3개를 제외하고 모든 제너릭 뷰에서 사용한다.queryset을 사용하면model속성은 무시된다.
template_name : TemplateView를 포함한 모든 제너릭 뷰에서 사용한다. 템플릿 파일명을 문자열로 지정한다.
context_object_name : 뷰에서 템플릿 파일에 전달하는 컨텍스트 변수명을 지정한다.
paginate_by : ListView와 날짜 기반 뷰(예, YearArchiveView)에서 사용한다. 페이징 기능이 활성화 된 경우 페이지당 출력 항목 수를 정수로 지정한다.
date_field : 날짜 기반 뷰(예, YearArchiveView)에서 사용한다. 이 필드의 타입은 DateField 또는 DateTimeField이다.
form_class : FormView, CreateView, UpdateView에서 폼을 만드는데 사용할 클래스를 지정한다.
success_url : FormView, CreateView, UpdateView, DeleteView에서 폼에 대한 처리가 성공한 후 리디이렉트할 URL 주소이다.
메소드 오버라이딩
def get_queryset() : 기본 뷰(View, Template, RedirectView) 3개를 제외하고 모든 제너릭 뷰에서 사용한다. 디폴트는queryset속성을 반환한다.queryset속성이 지정되지 않은 경우 모델 매니저 클래스의 all() 메소드를 호출해 QuerySet 객체를 생성해 반환한다.
def get_context_data(**kwargs) : 뷰에서 템플릿 파일에 넘겨주는 컨텍스트 데이터를 추가하거나 변경하는 목적으로 오버라이딩한다.
def form_valid(form)
<모델을 지정하는 방법 3가지>
model 속성 변수 지정
queryset 속성 변수 지정
def get_queryset() 메소드 오버라이딩
##실습
1. views.py 작성하기 전
django-admin startproject <project-name>
cd <project-name>
python manage.py startapp <app-name>
settings.py에 App, rest_framework추가
models.py에 모델 작성 및 migrate
serializer.py생성 및 작성
2. views.py 작성하기
1) 필요한 모듈 추가하기
- 사용할 모델, serializer , rest_framework 의 generics 추가
from .models import Post
from .serializer import PostSerializer
from rest_framework import generics
2) PostList 클래스 작성하기
- generics의 ListCreateAPIView 는 mixins에서 사용한 list 함수와 create 함수를 가지고 있는 class 이다.
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
3) PostDetail 클래스 작성하기
- genercis의 RetrieveUpdateDestoryAPIView 또한 mixins에서 사용한 함수들과 동일한 기능
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
3. urls.py 작성하기
- 앱 내부에 urls.py 생성 및 작성
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
urlpatterns = [
path("post", views.PostList.as_view()),
path("post/<int:pk>", views.PostDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
- 프로젝트 폴더 내부의 urls.py 에 include
from django.contrib import admin
from django.urls import path, include
import post.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(post.urls)),
]
-> 실행 결과 : http://127.0.0.1:8000/post로 접속하면 잘 작동하는 것을 확인할 수 있다.
5. ViewSet
rest_framework의 viewsets.py내부에는 4개의 클래스가 존재한다.
ViewSet
GenericViewSet
ReadOnlyModelViewSet
ModelViewSet
모두 간단하게 구성되어 mixins와 GenricViewSet, APIView등을 묶는 역할을 한다.
ReadOnlyModelViewSet
- 상속 받은 클래스
mixins.RetrieveModelMixin
mixins.ListModelMixin
GenericViewSet
상속받은 클래스로 보아 해당 viewset 역할은 retrieve 함수와 list 함수 기능을 가지고 있다
- 기능 : 특정 객체 가져오는 역할(retrieve) / 객체 목록을 가져오는 역할(list)
ReadOnly를 수행하는 viewSet 이다
아래와 같이 작성하면
기존 postlist, postDetail 클래스의 기능을 따로 작성하지 않아도 ReadOnlyModelViewSet을 상속받아 사용할 수 있다.
from rest_framework import viewsets
from .models import Post
from .serializer import PostSerializer
class PostViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Post.objects.all()
serializer_class =
-> customAPI 함수는 default로 GET 메서드로 처리된다. / 다른 메서드로 처리하고 싶다면 action의 format 인자로 지정 가능
%action decorator
@는 decorator, 장식자라고 부른다. ViewSet을 이용하면 CRUD는 간단하게 구현되나 다른 논리들을 구현할 때 @action를 사용한다. 개발자가 임의로 View를 설계할 수 있도록 해준다.
%renderer_classes
Response를 어떤 형식으로 Rendering시킬 것인가를 정의
renderer.JSONRenderer
renderer.BrowsableAPIRenderer
renderer.StaticHTMLRenderer
TemplateHTMLRenderer
등 여러가지가 있다. 기본 설정은 JSONRenderer와 BrowsableAPIRenderer다.
##실습해보기
viewSet 적용하기
1. views.py 작성하기 전
django-admin startproject <project-name>
cd <project-name>
python manage.py startapp <app-name>
settings.py에 App, rest_framework추가
models.py에 모델 작성 및 migrate
serializer.py생성 및 작성
2. views.py 작성하기
1) 필요한 모듈 추가
from .models import Post
from .serializer import PostSerializer
from rest_framework import viewsets
from rest_framework import renderers
from rest_framework.decorators import action
from django.http import HttpResponse
2) ReadOnlyModelViewSet을 상속해 클래스 작성하기
- viewsets의 ReadOnlyModelViewSet을 상속받아 작성한다. ReadOnlyModelViewSet을 상속받았으므로 읽기만 가능하다.
class PostViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
3. urls.py 작성하기
- post 앱 내부의 urls.py
from rest_framework.routers import DefaultRouter
from django.urls import include, path
from .views import PostViewSet
router = DefaultRouter()
router.register('', PostViewSet)
urlpatterns = [
path('post', include(router.urls))
]
- 프로젝트 폴더의 urls.py
from django.contrib import admin
from django.urls import path, include
import post.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(post.urls)),
]
>>실행결과
-http://127.0.0.1:8000/로 접속하면 아래와 같은 결과를 확인할 수 있다. DefaultRouter를 사용했기 때문에 PATH가 ""일때도 화면이 나온다.
-http://127.0.0.1:8000/post로 접속하면 사용가능한 HTTP Method가 ReadOnlyModelViewSet을 상속받았으므로 GET밖에 없다.
4. ModelViewSet 상속해 클래스 작성하기
viewsets의 ModelViewset 상속받은 PostViewSet 클래스 작성
사용할 모델과 serializer을 등록하는 것은 기존과 동일
추가적으로 @action 데코레이터를 이용해 custom api 작성
get 방식으로 @action Custom API Test를 띄우는 highlight 함수 작성
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
@action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
return HttpResponse("@action Custom API Test")
post로 처리하고 싶다면 @action(method=['post']) 와 같이 작성
>>실행결과
http://127.0.0.1:8000/post로 접속하면 사용가능한 HTTP Method가 GET외에도 POST가 추가된 것을 확인
Custom API 테스트
>http://127.0.0.1:8000/post/2/와 같이 Detail페이지로 접속하면 Extra Actions 스크롤 메뉴가 생긴 것을 확인할 수 있다.
스크롤 메뉴에서 highlight 버튼 클릭 시 아래와 같은 결과가 생성된다
6. Router
viewSet 복습
- ReadOnlyModelViewSet
retrieve()와 list()의 기능
- ModelViewSet
list(), create(), retrieve(), update() partial_update(), destroy()의 기능
path
viewSet을 하나의 path 함수로 처리할 수 있을까?
하나의 path로 ListView, DetailView 의 CRUD가 모두 처리 가능할까??
-> 앱 폴더 내부에 urls.py 생성(계층적 url 관리 위해 분할) ##아니 나는 urls.py를 완성하지 못하면 마이그레이트가 안된다.. 이거먼저!
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter() #ROUTER 객체 생성
router.register('post', views.PostViewSet) #ROUTER 객체의 REGISTER 함수(첫번째 인자 = URL, 함수)
urlpatterns = [
path('', include(router.urls))
]
#rest_framework는 ROUTER을 사용해 URL을 결정한다
#CRUD 기반으로 URL을 설정한다
-> 프로젝트 폴더 urls.py 에 모듈 추가
from django.contrib import admin
from django.urls import path, include
import post.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(post.urls)),
]
앱 폴더의 models.py 에 모델 클래스 정의 (post/models.py)
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
# Create your models here.
앱 폴더 내부에 serializer.py 생성 및 작성 (어떤 클래스의 어떤 필드를 사용할 것인지)
from .models import Post
from rest_framework import serializers
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['title', 'body']
# 모든 필드를 사용할 경우 '__all__' 사용 가능
views.py 작성하기
-> rest_framework 의 viewsets 모듈과 작성한 모델과 serializer 추가
from rest_framework import viewsets
from .models import Post
from .serializer import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
Django Rest Framework는 Class base View 이기에
view로서 class를 작성한다
viewsets의 ModelViewSet을 상속받는다.
##ROUTER
▪ ViewSet에는 여러가지 메소드(함수)들이 있다
ex) retrieve() , destroy(), …
▪ 이 모든 것을 하나의 path()로 처리해 주는 것은 불가능하다.
▪ Path함수를 묶어준다 == path함수의 두번째 인자로 오는 함수를 묶는다
-> Path(요청을 처리할 url, 요청을 인자로 받아 처리할 함수, namespace)
#실행 결과(api 서버 보기)
1. api root : urls.py 에 작성된 DefaultRouter 에 의해 만들어진 기본적인 환경 / 처음 보여지는 화면은 GET 요청을 할 수 있는 URL이 보여진다.
2.POST API
-request : 127.0.0.1/8000/post
-response
post 후 post/1로 들어가면 allow 부분에 put이 들어간 것을 볼 수 있음
각 객체에 pk 값 부여하기
-> serializer.py 파일의 PostSerializer 을 수정한다
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['id', 'title', 'body']
새로 고침 후 보면 id 값을 직접 확인할 수 있는 것을 볼 수 있다.
id 값 : 각 인스턴스에 붙는 고유 번호
Read Only 설정하기
-> serializer.py 파일의 PostSerializer을 수정한다
-> read_only_fields 에 read_only 속성을 적용할 필드를 tuple에 추가한다
-> 수정 시 read_only 부분이 true로 바뀌는 것을 볼 수 있다.
-> write_only부분도 같은 방법으로 수정하면된다!
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = "__all__"
read_only_fields = ("title",)