Django Rest_framework 게시판 만들기

2022. 3. 15. 22:07·Python/Django
728x90

지난번 Post 모델을 작성했던 부분을 다시 수정해보았습니다.

 

models.py
from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()

class Post(models.Model):
    id = models.AutoField(primary_key=True, null=False, blank=False)
    title = models.CharField(max_length=50)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE, related_name="post")
    content = models.TextField()

    def __str__(self):
        return self.title

id는 해당 테이블의 기본키로 primary_key를 설정하였고, 자동으로 값을 부여하기 위하여 AutoField를 사용했습니다.

또한 게시물의 작성 시간과 수정시간을 알기 위하여 craeted_at은 auto_now_add를 설정하고, updated_at에는 auto_now를 설정하였습니다.

게시글을 작성한 사람도 있어야 하기 때문에 user를 외래키로 받아왔고 user가 삭제된다면 해당 게시물도 삭제하기 위해

on_delete를 CASCADE 해주었습니다.

그리고 django의 ORM 기능을 활용하기 위하여 user에 related_name을 설정해주었습니다.

* ORM모델은 Query문 없이 django에서 DB와 소통하기 위한 것입니다.

 

그리고 모델을 다시 정의하였기 때문에 마이그레이션을 다시 진행합니다.

python manage.py makemigrations
python manage.py migrate
마이그레이션을 진행하다
First parameter to ForeignKey must be either a model, a model name, or the string 'self' 해당 에러를 마주쳤는데
분명 외래키 모델을 지정해줬음에도 오류가 생겨 매우 의아했다. 코드를 다시 살펴보니
User = get_user_model() <- 이 부분을 User = get_user_model로 작성했던 것...
코드를 차근차근 살펴보자...

 

 

지난번 PostgreSQL CRUD 만들기 포스팅을 보면 https://magicmk.tistory.com/7

 

Django + PostgreSQL CRUD 만들기

저번 포스팅에서 Django와 PostgreSQL을 연동하는 과정을 거쳤으니 이번에는 직접 모델 정의하고 CRUD를 만들어보겠습니다. Django Model 정의 만들어진 App 안에 Models.py에서 클래스를 추가한다. from django.

magicmk.tistory.com

마이그레이션 과정에서 오류가 나서 이름을 바꾼 뒤 migrate를 해줬는데 그러지 않고

python manage.py migrate {app 이름} zero
python manage.py migrate {app 이름}

이렇게 진행하면 해결할 수 있습니다.

 

 

serializer.py
from .models import Post
from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):
    user = serializers.ReadOnlyField(source = 'user.username')
    class Meta:
        model = Post
        fields = ['id', 'title', 'created_at', 'user', 'content']

뒤에서 설명할 views.py에서 user값을 넘겨받을 것이기 때문에 serializer에서 해당 값을 받습니다.

views.py에서 넘겨준 user에 name을 받기 위하여 source='user.username'으로 설정하였습니다.

 

 

views.py
from .models import Post
from .serializer import PostSerializer
from rest_framework import viewsets
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from .permissions import IsOwnerOrReadOnly


class PostViewSet(viewsets.ModelViewSet):
    authentication_classes = [BasicAuthentication, SessionAuthentication]
    permission_classes = [IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
    queryset = Post.objects.all()
    serializer_class = PostSerializer

    def perform_create(self, serializer):
        serializer.save(user = self.request.user)

PostSerializer의 user 필드에 user값을 전달하기 위하여 perform_create 메서드를 추가하였습니다.

ViewSets에서 perform_create를 사용하면 기존의 create 함수를 재정의 할 수 있습니다.

또한 게시글을 작성할 때 user의 내용을 담아오는데 로그인 하지 않은 사용자가 게시글을 작성하면 에러가 발생하기

때문에 authentication과 permission을 사용했습니다.

하지만 그냥 BasicAuthentication, SessionAuthentication, IsAuthenticatedOrReadOnly만 사용한다면

로그인을 한 유저가 아무 게시글이나 수정 또는 삭제 등을 할 수 있기 때문에 개인을 판별하는 것이 필요합니다.

따라서 해당 앱 내부에 permissions.py 파일을 생성합니다.

 

permissions.py
from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True
        return obj.user == request.user

간단하게 SAFE_METHOD (GET,HEAD,OPTIONS) 요청은 허용하고, PUT, PATCH, DELETE 등은 해당 게시글의 user와

로그인되어 있는 user가 동일한 경우만 권한을 허용합니다.

그 뒤 views.py로 돌아가 permission_classes에 추가하면 됩니다.

 

urls.py
from django.urls import path, include
from .views import PostViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register('post', PostViewSet)

urlpatterns = [
    path('', include(router.urls))
]

url의 경우에는 특별한 사항은 없습니다.

 

 

마지막으로 서버를 실행하여 테스트를 해보면

post 내용 전송
성공

 

Database 확인

DB에도 정상적으로 데이터가 들어가는 것을 확인했습니다. 그럼 이상으로 포스팅 끝.

저작자표시 비영리

'Python > Django' 카테고리의 다른 글

Django Rest Framework란?  (0) 2022.04.14
Django + PostgreSQL CRUD 만들기  (0) 2022.02.23
Django와 PostgreSQL 연동  (1) 2022.02.23
'Python/Django' 카테고리의 다른 글
  • Django Rest Framework란?
  • Django + PostgreSQL CRUD 만들기
  • Django와 PostgreSQL 연동
요술공주밍키
요술공주밍키
조금씩이라도 꾸준히..
  • 요술공주밍키
    삽질의흔적
    요술공주밍키
  • 전체
    오늘
    어제
    • 분류 전체보기 (128) N
      • Java (42)
        • Spring Boot (14)
        • Spring Boot 게시판 (14)
        • 공중화장실 찾기 (4)
        • 쇼핑몰 (8)
      • JavaScript (8)
        • NodeJS (2)
      • Python (5)
        • Django (4)
      • Server (10)
        • Docker (4)
        • K8S (0)
        • Jenkins (1)
      • 알고리즘 (21) N
        • 프로그래머스 (17)
        • 백준 (4) N
      • Etc (21)
        • 개발 팁 (1)
      • 일상 (19)
        • 독서 포스트 (17)
        • 회고록 (2)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
요술공주밍키
Django Rest_framework 게시판 만들기

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.