현제의 현재이야기

[OSOD] Nested Serializer 및 views.py 작성 본문

DRF/OSOD

[OSOD] Nested Serializer 및 views.py 작성

현재의 현제 2023. 2. 4. 12:47

models.py

from django.db import models
from accounts.models import User

class Sentence(models.Model):
    sentence = models.CharField(max_length=200)
    discription =  models.CharField(max_length=200)
    created_at = models.DateTimeField(auto_now_add=True, null=True)

class Post(models.Model):
    body = models.CharField(max_length=200)
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    sentence = models.ForeignKey(Sentence, on_delete=models.CASCADE, null=True)
    like_users = models.ManyToManyField(User, related_name='like', null=True)
    like_num = models.IntegerField(null=True, default=0)
    bool_like_users = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True, null=True)

class Subsription(models.Model):
    sub_email = models.EmailField(max_length=50)

 

serializers.py

from rest_framework import serializers
from .models import *
from accounts.serializers import UserDetailSerializer
from accounts.models import User


class SentenceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Sentence
        fields = ['sentence', 'discription', 'created_at']
        
class PostSerializer(serializers.ModelSerializer):
    user = UserDetailSerializer(read_only=True)
    class Meta:
        model = Post
        fields = ["id", "user", "body", "sentence", "like_num", "bool_like_users", "created_at"]

class LikeUsersSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'like_num', 'bool_like_users']
  • nested serializer 쓰는 방법은 해당 필드에 시리얼라이저를 넣어주면 된다. 그러면 fk로 받은 것을 저렇게 nested 형식으로 나오게 해준다.

이렇게 잘 나온다.

#views.py
class SentenceRetrieveUpdateView(RetrieveUpdateAPIView):
    serializer_class = SentenceSerializer

    def get_queryset(self):
        return Sentence.objects.all()
        
#urls.py
path('sentence/<int:pk>/', views.SentenceRetrieveUpdateView.as_view(), name='RetrieveUpdate'),
  • RetrieveUpdate 및 destory 등등의 APIview들은 url로 int를 받고 필터링을 하지 않아도 자동으로 필터링을 해준다.

메인 페이지

class PostOrderView(ListAPIView):
    serializer_class = PostSerializer
    pagination_class = PostPageNumberPagination

    def get_queryset(self):
        self.cmd = self.request.META.get('HTTP_CMD')
        sentence_id = self.kwargs.get("sentence_id")
        user_id = self.request.user.id
        if self.cmd == "latest":
            return Post.objects.filter(sentence_id=sentence_id).order_by('-created_at')
        elif self.cmd == "likes":
            return Post.objects.filter(sentence_id=sentence_id).order_by('-like_num')
        elif self.cmd == "my":
            return Post.objects.filter(sentence_id=sentence_id, user_id=user_id).order_by('-created_at')

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        for post in queryset:
            if post.like_users.filter(pk=self.request.user.id).exists():
                post.bool_like_users = True
            else:
                post.bool_like_users = False
            post.save(update_fields=['bool_like_users'])
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
  • 헤더의 값을 받는 방법: self.request.META.get('HTTP_~~')
  • url에서 인자를 받아오는 방법: self.kwargs.get("~~") -> kwargs는 키, 벨류 값으로 들어오기 때문에 키 값을 ~~에 적어준다.
  • if 문으로 정렬의 방법을 바꾸었다.
  • list 메소드를 오버라이딩해서 리스트를 불러올 때, 내가 좋아요를 누른 게시글이면 bool_like_user의 값을 바꿔주어 하트를 칠할 수 있게 만들었다.
  • 그리고나서 시리얼라이저로 담고 전송

 

오버라이딩 생각보다 할만하다! 원리만 안다면.. class 형 + 제네릭을 사용하니깐 훨씬 편리하다. 

 

 

-참고 블로그-

 

DRF에서 Nested Serializer 사용법

gaussian37's blog

gaussian37.github.io

 

 

DRF 공부하기 (6) :: ModelSerializer

https://velog.io/@jcinsh/DRF-5-ModelSerializer 의 글을 베끼며 공부해봄

velog.io

 

 

DRF에서 복합키로 instance 찾기

Django Rest Framework의 API에서 DB의 데이터에 접근하는 메소드는 두 가지가 있다. UPDATE와 DELETE가 그 예시이다. 해당 메소드 코드를 보면, 다음과 같이 데이터에 접근하는 것을 볼 수 있다.

velog.io

 

JWT 토큰 request 처리 참고

 

JWT에서 Django request.user 까지의 여정

Django에서 request의 유저를 알기 위해선 request.user를 통해 알 수 있다. Django에서 지원하는 session 방식의 로그인 / rest_framework에서 지원하는 JWT 등 로그인을 하면 request.user의 정보를 가져올 수 있다.

uiandwe.tistory.com

Comments