스파르타코딩클럽
내일배움캠프 AI 웹개발자양성과정 2회차
DRF 강의 3일차 과제
0. 과제내용
- blog 앱에 <게시글, 사용자, 내용>이 포함된 comment 테이블을 작성해주세요
- 외래 키를 사용해서 Article, User 테이블과 관계를 맺어주세요
- admin.py에 comment를 추가해 자유롭게 생성, 수정 할 수 있도록 해주세요
- serializer를 활용해 로그인 한 사용자의 기본 정보와 상세 정보를 리턴해 주는 기능을 만들어주세요
- 4번의 serializer에 추가로 로그인 한 사용자의 게시글, 댓글을 리턴해주는 기능을 구현해주세요
- blog 앱에 title / category / contents를 입력받아서 게시글을 작성하는 기능을 구현해주세요
- 만약 title이 5자 이하라면 게시글을 작성할 수 없다고 리턴해주세요
- 만약 contents가 20자 이하라면 게시글을 작성할 수 없다고 리턴해주세요
- 만약 카테고리가 지정되지 않았다면 카테고리를 지정해야 한다고 리턴해주세요
- custom permission class를 활용해 가입 후 3일 이상 지난 사용자만 게시글을 쓸 수 있도록 해주세요
- 테스트 할 때에는 가입 후 3분 이상 지난 사용자가 게시글을 쓸 수 있게 해주세요
- join_date는 datetime field로 만들어주세요
2. 외래 키를 사용해서 Article, User 테이블과 관계를 맺어주세요
class Comment(models.Model):
comment = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
article = models.ForeignKey(Article, on_delete=models.CASCADE)
def __str__(self):
return f'{self.article.title} comment - {self.author.username}'
from django.contrib import admin
from .models import Category, Article, Comment
admin.site.register(Category)
admin.site.register(Article)
admin.site.register(Comment)
4. serializer를 활용해 로그인 한 사용자의 기본 정보와 상세 정보를 리턴해 주는 기능을 만들어주세요
class HobbySerializer(serializers.ModelSerializer):
same_hobby_people = serializers.SerializerMethodField()
def get_same_hobby_people(self, obj):
user = self.context.get('request').user
people = obj.userprofile_set.exclude(user=user)
name_list = [ person.user.username for person in people ]
return name_list
class Meta:
model = Hobby
fields = ['hobby', 'same_hobby_people']
class UserProfileSerializer(serializers.ModelSerializer):
hobby = HobbySerializer(many=True)
class Meta:
model = UserProfile
fields = ['age', 'hobby']
class UserSerializer(serializers.ModelSerializer):
userprofile = UserProfileSerializer()
class Meta:
model = User
fields = ["username", "fullname", "email", "userprofile"]
class UserView(APIView):
permission_classes = [permissions.AllowAny]
def get(self, request):
user = request.user
if not user.is_authenticated:
msg = '로그인을 해주세요'
return Response({'message': msg})
return Response(UserSerializer(user, context={'request': request}).data)
5. 4번의 serializer에 추가로 로그인 한 사용자의 게시글, 댓글을 리턴해주는 기능을 구현해주세요
from user.serializers import UserSerializer
from .models import Article, Comment, Category
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ["category_name"]
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ['author', 'comment']
class ArticleSerializer(serializers.ModelSerializer):
comments = serializers.SerializerMethodField()
category = CategorySerializer(many=True)
author = serializers.SerializerMethodField()
def get_author(self, obj):
author_name = obj.author.username
return author_name
def get_comments(self, obj):
comments = Comment.objects.filter(article=obj)
return [f'{comment.author} - {comment.comment}' for comment in comments ]
class Meta:
model = Article
fields = ["title", "author", "category", "content", "comments"]
class UserArticle(APIView):
permission_classes = [RegistedMoreThanAWeekUser]
def get(self, request):
user = request.user
if not user.is_authenticated:
msg = '로그인을 해주세요.'
return Response({'message': msg})
articles = Article.objects.filter(author=user)
return Response(ArticleSerializer(articles, many=True).data)
6. blog 앱에 title / category / contents를 입력받아서 게시글을 작성하는 기능을 구현해주세요
- 만약 title이 5자 이하라면 게시글을 작성할 수 없다고 리턴해주세요
- 만약 contents가 20자 이하라면 게시글을 작성할 수 없다고 리턴해주세요
- 만약 카테고리가 지정되지 않았다면 카테고리를 지정해야 한다고 리턴해주세요
class UserArticle(APIView):
def get(self, request):
...
def post(self, request):
title = request.data['title']
categorys = request.data['categorys']
content = request.data['content']
if len(title) <= 5:
msg = 'title이 5자 이하이면 게시글을 작성할 수 없습니다.'
return Response({'message': msg})
if len(content) <=20:
msg = 'content가 20자 이하이면 게시글을 작성할 수 없습니다.'
return Response({'message': msg})
if not categorys or len(categorys) == 0:
msg = 'category를 지정해야합니다.'
return Response({'message': msg})
categorys = [Category.objects.get(category_name=category) for category in categorys]
user = request.user
article = Article.objects.create(author=user, title=title, content=content)
article.category.set(categorys)
article.save()
return Response({'message': '게시글 저장 완료!'})
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 RegistedMoreThanAWeekUser(BasePermission):
"""
가입일 기준 3일 이상 지난 사용자만 접근 가능
"""
message = '가입 후 3일 이상 지난 사용자만 사용하실 수 있습니다.'
def has_permission(self, request, view):
return bool(request.user and request.user.join_date < (timezone.now() - timedelta(days=3)))
from permissions import RegistedMoreThanAWeekUser
class UserArticle(APIView):
permission_classes = [RegistedMoreThanAWeekUser]
def get(self, request):
...
def post(self, request):
...
Github
https://github.com/kimphysicsman/nbcamp-drf-2