현제의 현재이야기
[OSOD] Nested Serializer 및 views.py 작성 본문
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 형 + 제네릭을 사용하니깐 훨씬 편리하다.
-참고 블로그-
JWT 토큰 request 처리 참고
'DRF > OSOD' 카테고리의 다른 글
[OSOD] 비밀번호 변경 및 리셋 관련 (0) | 2023.02.16 |
---|---|
[OSOD] SerializerMethodField()에 대하여 (0) | 2023.02.13 |
[OSOD] 회원가입 인증 이메일 (0) | 2023.01.29 |
[OSOD] dj-rest-auth custom + logout (0) | 2023.01.26 |
[OSOD] dj-rest-auth + jwt 로그인 (0) | 2023.01.26 |
Comments