TIL_220617_DRF ๊ฐ์
- -
DRF ์ ๊ฝ Serializer ์ ๋ํด์ ๋ฐฐ์ฐ๊ณ ,
Serializer ๋ก ๊ณผ์ ๋ฅผ ๋ฐ์๋ค.
์ด๋์ ๋ ์ดํด๋ฅผ ํ๋ค๊ณ ์๊ฐํ๋๋ฐ,
์๊ฐ๋ณด๋ค ์์๊ณผ ๋ค๋ฅธ Serializer ์ถ๊ฐ ๋ถ๋ถ์ ๋ํด์ ์ ๋๋ก ์ดํดํ์ง ๋ชปํ ๋ถ๋ถ์ด ์์ด
๋๋ด ๊ณผ์ ๋ฅผ ์์ฑํ ์ ์์๋ค..
๊ทธ๋๋ ํด์ค ๊ฐ์๋ฅผ ํตํด ๋ง์ง๋ง๊น์ง ์ฐ๋จนํด๋ณด์๋ค.
์๋ฌ ๋ ธํธ
์ฌ์ค ์๋ฌ๋ผ๊ธฐ ๋ณด๋ค๋ ๋ด๊ฐ ์ค์ํ ๋ด์ฉ์ด์ง๋ง, ๋ ๋ฒ ์ค์ํ์ง ์๊ธฐ ์ํด ์ ์ด๋๋ค.
<๊ด๋ฆฌ์ ๊ณ์ ์๋ฌ>
์์ธ :
1) ํ์์ดํ ์ ์์ ์๋ก์ด ํ๋ก์ ํธ ์์ฑํ๊ณ ์์.
2) ํ์์ดํ 2๋ฒ ๋ฌธ์ ์์ USERNAME_FIELD ๋ฅผ ๋ณ๊ฒฝํด๋ ๊ณ์ ๋ฐ๋์ง ์๋ ๊ธฐ์ดํ ํ์
3) ์๋ฌ ์ฝ๋๋ ๋จ์ง ์๊ณ ๊ณ์ ์ฌ์ฉ์ ์ด๋ฆ๋ถํฐ ์์ฑํ๋ผ๊ณ ํจ.
ํด๊ฒฐ : AUTH_USER_MODEL = 'user.User'
๊ณ์ ๋ชจ๋ธ์ ์์ ์ด ์ปค์คํ
ํ ๊ณ์ ๋ชจ๋ธ๋ก ๋ฉ์ธ์ผ๋ก ์ง์ ์ ๊ผญ ํด์ค์ผ ์ฅ๊ณ ์ ๊ธฐ๋ณธ ๋ชจ๋ธ์์ ์์ ์ด ์ปค์คํ
ํ ๋ชจ๋ธ๋ก ์ ์ฉ๋์ด ์ฌ์ฉ ๊ฐ๋ฅ.
(๊ธฐ๋ณธ์ ์ธ๊ฑด๋ฐ.. ๊ด๋ฆฌ์ ๋ชจ๋ธ ์ง์ ์ ์ํด์ค ์ค์.. ใ
)
<input ์ด ์ ์์ ์ผ๋ก ๋ฐ์ ์ ์๋ ์ํฉ>
# ๊ธ ์์ฑ ๊ธฐ๋ฅ ๊ตฌํ
def post(self, request):
user = request.user
title = request.data.get("title", "")
contents = request.data.get(<<"contents">>, "")
category = request.data.get("category", [])
====================================================================
<<< input >>>
{
"title" : "์๋
ํ์ธ์ ๋ฐ๊ฐ์ต๋๋ค.",
<<"contents">> : "๊ธ ๋ด์ฉ ์
๋๋ค. ์์ฐ ๋นก๋นก์ด ์์ฃ ์จ์ผ!!! ํธ์ฐ!!!!!!",
"category" : [4, 5]
}
๋ฆฌํ์คํธ๋ก ๋ฐ์์ค๋ ํ๋๋ช
์ ๊ผญ ์
๋ ฅ๋ฐ์ดํฐ ๋ช
๊ณผ ๊ฐ์์ผํ๋ค.
์ฐธ๊ณ ์๋ฃ
์ฐธ๊ณ ๊ฐ ๋์๋ ์๋ฃ๋ค์ ์ฐพ์๋ดค๋ค.
Serializer ์ฌ์ฉ ๋ฐฉ๋ฒ
์ถ์ฒ ์ ํฌ๋ธ : https://www.youtube.com/watch?v=V4NjlXiu5WI
4์ผ์ฐจ ๊ณผ์
1. blog ์ฑ์ <๊ฒ์๊ธ, ์ฌ์ฉ์, ๋ด์ฉ>์ด ํฌํจ๋ comment ํ ์ด๋ธ์ ์์ฑํด์ฃผ์ธ์
class Comment(models.Model):
# Article ์ ์์ฑํ ์ฝ๋ฉํธ์ ์ถ์ฒ(์์ฑ์) / CASCADE ๋๊ธ์ ์์ฑ์ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ํจ๊ป ๋๊ธ ๋ฐ์ดํฐ ์ญ์ ์ค์
user = models.ForeignKey('user.User', verbose_name="๋๊ธ ์์ฑ์", on_delete=models.CASCADE)
# Article ๊ณผ์ ๋๊ธ ๊ด๊ณ ์ ์ / CASCADE ๊ฒ์๊ธ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ํจ๊ป ๋๊ธ ๋ฐ์ดํฐ ์ญ์ ์ค์
article = models.ForeignKey(Article, verbose_name="๋๊ธ์ ์์ฑํ ๊ธ", on_delete=models.CASCADE)
content = models.TextField("๋๊ธ ๋ด์ฉ")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.user.username} ๋์ด ์์ฑํ์ ๋๊ธ์
๋๋ค."
2. ์ธ๋ ํค๋ฅผ ์ฌ์ฉํด์ Article, User ํ
์ด๋ธ๊ณผ ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ์ธ์
# Article ์ ์์ฑํ ์ฝ๋ฉํธ์ ์ถ์ฒ(์์ฑ์) / CASCADE ๋๊ธ์ ์์ฑ์ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ํจ๊ป ๋๊ธ ๋ฐ์ดํฐ ์ญ์ ์ค์
user = models.ForeignKey('user.User', verbose_name="๋๊ธ ์์ฑ์", on_delete=models.CASCADE)
# Article ๊ณผ์ ๋๊ธ ๊ด๊ณ ์ ์ / CASCADE ๊ฒ์๊ธ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ํจ๊ป ๋๊ธ ๋ฐ์ดํฐ ์ญ์ ์ค์
article = models.ForeignKey(Article, verbose_name="๋๊ธ์ ์์ฑํ ๊ธ", on_delete=models.CASCADE)
3. admin.py์ comment๋ฅผ ์ถ๊ฐํด ์์ ๋กญ๊ฒ ์์ฑ, ์์ ํ ์ ์๋๋ก ํด์ฃผ์ธ์
from django.contrib import admin
from blog.models import Comment
# Register your models here.
admin.site.register(Comment)
4. serializer๋ฅผ ํ์ฉํด ๋ก๊ทธ์ธ ํ ์ฌ์ฉ์์ ๊ธฐ๋ณธ ์ ๋ณด์ ์์ธ ์ ๋ณด๋ฅผ ๋ฆฌํดํด ์ฃผ๋ ๊ธฐ๋ฅ์ ๋ง๋ค์ด์ฃผ์ธ์
class HobbySerializer(serializers.ModelSerializer):
# ์ด ๊ธฐ๋ฅ์ ํตํด ์์ ์ ์ทจ๋ฏธ์ ํด๋นํ๋ ์ ์ ์ ๋ณด๋ฅผ ๋ถ๋ฌ์ฌ ์ ์์.
# ์์ ์ด ์ํ๋ ๋ฉ์๋ ํ๋ ์์ฑ ๊ฐ๋ฅ
same_hobby_users = serializers.SerializerMethodField()
# SerializerMethodField() ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ get_same_hobby_users ๊ผญ ํ์
def get_same_hobby_users(self, obj):
# obj : hobby model ์ obj
user_list = []
for user_profile in obj.userprofile_set.all():
user_list.append(user_profile.user.username)
# return [up.user.username for up in obj.userprofile_set.all()] ์ถ์ฝ์
return user_list
class Meta:
model = Hobby
fields = ['name', 'same_hobby_users']
class UserProfileSerializer(serializers.ModelSerializer):
hobby = HobbySerializer(many=True) # input data queryset ์ผ ๊ฒฝ์ฐ
class Meta:
model = UserProfile
# ๋ถ๋ฌ์ค๊ณ ์ ํ๋ user ์ ๊ธฐ๋ณธ ์ ๋ณด์ ์์ธ ์ ๋ณด ๋ถ๋ฌ์ค๊ธฐ
fields = ['introduction', 'birthday', 'age', 'hobby']
# __all__ ์ฌ์ฉ ๋ฐฉ๋ฒ๋ ์์ง๋ง ์ฌ์ฉํ์ง ์๋ ์ด์ ๋ ๋ถํ์ํ ์ ๋ณด๋ ํจ๊ป ๋ถ๋ฌ์ค๊ธฐ ๋๋ฌธ์
# ํน์ ์ ๋ณด์ ํด๋นํ๋ ์ ๋ณด๋ง์ ๋ฐ๊ธฐ ์ํด์๋ ์ง์ ์ค์ ํด์ฃผ๋ ๊ฒ์ด ์ข๋ค.
class UserSerializer(serializers.ModelSerializer):
# object
userprofile = UserProfileSerializer()
class Meta:
model = User
# ์ญ์ฐธ์กฐ๋ก userprofile ์ ๋ณด ๋ถ๋ฌ์ค๊ธฐ
fields = ["username", "password", "fullname", "email", "join_date", "userprofile"]
5. 4๋ฒ์ serializer์ ์ถ๊ฐ๋ก ๋ก๊ทธ์ธ ํ ์ฌ์ฉ์์ ๊ฒ์๊ธ, ๋๊ธ์ ๋ฆฌํดํด์ฃผ๋ ๊ธฐ๋ฅ์ ๊ตฌํํด์ฃผ์ธ์
class UserSerializer(serializers.ModelSerializer):
# object
userprofile = UserProfileSerializer()
# ํด๋น ์ ์ ์ ๊ฒ์๊ธ ๋ฆฌ์คํธ
userarticle = ArticleSerializer(source="article_set" ,many=True)
class Meta:
model = User
# ์ญ์ฐธ์กฐ๋ก userprofile ์ ๋ณด ๋ถ๋ฌ์ค๊ธฐ
fields = ["username", "password", "fullname", "email", "join_date", "userprofile", "userarticle"]
6. blog ์ฑ์ title / category / contents๋ฅผ ์
๋ ฅ๋ฐ์์ ๊ฒ์๊ธ์ ์์ฑํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํด์ฃผ์ธ์
- ๋ง์ฝ title์ด 5์ ์ดํ๋ผ๋ฉด ๊ฒ์๊ธ์ ์์ฑํ ์ ์๋ค๊ณ ๋ฆฌํดํด์ฃผ์ธ์
- ๋ง์ฝ contents๊ฐ 20์ ์ดํ๋ผ๋ฉด ๊ฒ์๊ธ์ ์์ฑํ ์ ์๋ค๊ณ ๋ฆฌํดํด์ฃผ์ธ์
- ๋ง์ฝ ์นดํ
๊ณ ๋ฆฌ๊ฐ ์ง์ ๋์ง ์์๋ค๋ฉด ์นดํ
๊ณ ๋ฆฌ๋ฅผ ์ง์ ํด์ผ ํ๋ค๊ณ ๋ฆฌํดํด์ฃผ์ธ์
# ๊ธ ์์ฑ ๊ธฐ๋ฅ ๊ตฌํ
def post(self, request):
user = request.user
title = request.data.get("title", "")
contents = request.data.get("contents", "")
category = request.data.get("category", [])
# ๊ธ์์ ์กฐ๊ฑด ์ดํ์ผ ๊ฒฝ์ฐ
if len(title) <= 5:
return Response({"error" : "ํ์ดํ์ 5์ ์ด์ ์์ฑํ์
์ผ ํฉ๋๋ค."}, status=status.HTTP_400_BAD_REQUEST)
# ๊ธ์์ ์กฐ๊ฑด ์ดํ์ผ ๊ฒฝ์ฐ
if len(contents) <= 20:
return Response({"error" : "๊ธ ๋ด์ฉ์ 20์ ์ด์ ์์ฑํ์
์ผ ํฉ๋๋ค."}, status=status.HTTP_400_BAD_REQUEST)
if not category:
return Response({"error" : "์นดํ
๊ณ ๋ฆฌ๊ฐ ์ง์ ๋์ง ์์์ต๋๋ค."}, status=status.HTTP_400_BAD_REQUEST)
article = ArticleModel(
user = user,
title = title,
content = contents
)
article.save()
article.category.add(*category)
return Response({"message": "์ฑ๊ณต!"}, status=status.HTTP_200_OK)
7. custom permission class๋ฅผ ํ์ฉํด ๊ฐ์
ํ 3์ผ ์ด์ ์ง๋ ์ฌ์ฉ์๋ง ๊ฒ์๊ธ์ ์ธ ์ ์๋๋ก ํด์ฃผ์ธ์
- ํ
์คํธ ํ ๋์๋ ๊ฐ์
ํ 3๋ถ ์ด์ ์ง๋ ์ฌ์ฉ์๊ฐ ๊ฒ์๊ธ์ ์ธ ์ ์๊ฒ ํด์ฃผ์ธ์
- join_date๋ datetime field๋ก ๋ง๋ค์ด์ฃผ์ธ์
from rest_framework.permissions import BasePermission
from datetime import timedelta
from django.utils import timezone
class RegisterdMoreThanThreeDaysUser(BasePermission):
'''
๊ฐ์
์ผ ๊ธฐ์ค 3์ผ ์ด์ ์ง๋ ์ฌ์ฉ์๋ง ์ ๊ทผ ๊ฐ๋ฅ
'''
message = '๊ฐ์
ํ 3์ผ ์ด์ ์ง๋ ์ฌ์ฉ์๋ง ์ฌ์ฉํ์ค ์ ์์ต๋๋ค.'
def has_permission(self, request, view):
user = request.user
# ํจ์ถ์ ์กฐ๊ฑด 1) ๋ก๊ทธ์ธ ์ฌ์ฉ์์ธ๊ฐ ์กฐ๊ฑด 2) ๊ฐ์
์ผ ๊ธฐ์ค 3์ผ์ด ์ง๋ฌ๋๊ฐ
return bool(user.is_authenticated and request.user.join_date < (timezone.now() - timedelta(days=3)))
====================================================================
class ArticleView(APIView):
permission_classes = [RegisterdMoreThanThreeDaysUser] # ์ปค์คํ
permissions
'๐ฆ ๋ด์ผ๋ฐฐ์์บ ํ > TIL(Today I Learned)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
TIL_220621_DRF ๊ฐ์ (0) | 2023.01.01 |
---|---|
TIL_220620_DRF ๊ฐ์ (0) | 2023.01.01 |
TIL_220616_DRF ๊ฐ์ (0) | 2023.01.01 |
TIL_220615_DRF ๊ฐ์ (0) | 2023.01.01 |
TIL_220614_ํ ํ๋ก์ ํธ django (0) | 2023.01.01 |
๋น์ ์ด ์ข์ํ ๋งํ ์ฝํ ์ธ
์์คํ ๊ณต๊ฐ ๊ฐ์ฌํฉ๋๋ค