- Django Rest Framework
- restful한 api 설계를 할 수 있다.
- 미디어 파일과 스태틱 파일에 대해 이해한다.
- 게시글 모델과 조회/업로드를 위한 serializer를 만들 수 있다.
- 이미지를 포함한 게시글 기능을 개발할 수 있다.
- 포스트맨으로 백엔드 개발을 하면서 테스팅을 할 수 있다.
- drf에서 댓글 기능을 개발할 수 있다.
- drf에서 좋아요 기능을 개발할 수 있다.
- drf에서 follow 기능을 개발할 수 있다.
- many-to-many 관계를 설정하는 경우와 방법, 그리고 related_name의 사용방법을 이해한다.
[restful한 api 설계]
- 어떠한 기능들을 만들지 먼저 url과 views 파일의 골격을 만들어 준다.
- 즉, 어떤 url에 접속하면 어떤 method를 통해서 불러오고 게시하고 수정하고 삭제하고 등의 메서드 함수를 정의 해준뒤 pass로 먼저 골격을 잡아 준다.
[Media Image - Static File]
How to manage static files (e.g. images, JavaScript, CSS) | Django documentation | Django
Django The web framework for perfectionists with deadlines. Toggle theme (current theme: auto) Toggle theme (current theme: light) Toggle theme (current theme: dark) Toggle Light / Dark / Auto color theme Overview Download Documentation News Community Code
docs.djangoproject.com
- static file : 사용자의 요청에 따라 변경되는것이 아닌, 요청 그대로의 것을 보여주는 것이다.
- media file : 사용자가 올리는 파일
- pillow : 파이선에서 이미지를 다룰 때 쓰는 라이브러리 → 설치 필수
pip install Pillow
- 이미지 파일 업로드 시 설정
- settings.py에
# ROOT / URL 경로를 설정해줘야 한다.
STATIC_ROOT = BASE_DIR / "static"
STATIC_URL = "/static/"
MEDIA_ROOT = BASE_DIR / "media"
MEDIA_URL = "/media/"
- django → urls.py에
# 추가 임포트 해주기
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path()
]
# static 파일에 접근하기 위해 추가 세팅
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
[게시글 모델과 조회/업로드 - serializer]
# articles APP
- serializer.py 에서 Article model object 를 모두 받아온다
- 받아온 뒤 views.py에서 받아온 objects를 serializer화 시켜주고
- serializer.data로 보여준다.
- 만약에 Article model object 중에 내가 필요한 정보만 가져오고 싶으면,
# '__all__' 에서 내가 필요한 내용만 가져올 수 있도록 커스터마이징! (class 재정의)
fields = ("pk", "title", "image", "update_at", "user")
- serializers.py
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = '__all__'
# def post
class ArticleCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ("title", "image", "content")
# def get
class ArticleListSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField()
# 여기서 정의된 user의 email이 위에 user값에 들어가게 된다
def get_user(self, obj):
return obj.user.email
class Meta:
model = Article
fields = ("pk", "title", "image", "update_at", "user")
# 원래 여기서 user 값은 id 값으로 들어 왔었지만 그럼 user가 누군지 정확히 알 수 없기 때문에 14~17번 코드의 정의로 user 값에 email이 들어가도록 설정해준다.
[drf에서 댓글 기능을 개발]
# articles APP
- serializers.py
# 달려있는 댓글 모두 불러오기
class CommentSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField()
# 여기서 정의된 user의 email이 위에 user값에 들어가게 된다
def get_user(self, obj):
return obj.user.email
class Meta:
model = Comment
# fields = '__all__'
# fields : all에서 1개만 제외할때는 exclude 쓸 수 있음
exclude = ('article', )
# 댓글 달기
class CommentCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
# fields가 한개더라도 무조건 ',' 붙여줘야 함 -> 안그러면 str로 인식
fields = ("content",)
- views.py
class CommentView(APIView):
def get(self, request, article_id):
article = Article.objects.get(id=article_id)
comments = article.comment_set.all()
serializer = CommentSerializer(comments, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request, article_id):
serializer = CommentCreateSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user = request.user, article_id=article_id)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
-----------------------------------------------------------------------------
class CommentDetailView(APIView):
def put(self, request, comment_id, article_id):
comment = get_object_or_404(Comment, id=comment_id)
if request.user == comment.user:
serializer = CommentCreateSerializer(comment, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response("권한이 없습니다", status=status.HTTP_403_FORBIDDEN)
def delete(self, request, comment_id, article_id):
comment = get_object_or_404(Comment, id=comment_id)
if request.user == comment.user:
comment.delete()
return Response("삭제 완료", status=status.HTTP_204_NO_CONTENT)
else:
return Response("권한이 없습니다", status=status.HTTP_403_FORBIDDEN)
[drf에서 좋아요 기능]
# articles APP
- models.py 에 좋아요 필드 추가
likes = models.ManyToManyField(User, related_name="like_articles")
👉 좋아요는 내가 많은 사람들에게 누르거나 다른 사용자들이 나에게 좋아요를 날릴 수 있기 때문에 ManyToManyField 사용!
- 기존 serializers.py에 정의된 class 안 like를 정의해준뒤
likes = serializers.StringRelatedField(many=True)
- 해당 정의된 class를 이용해 views.py에서 작업
class LikeView(APIView):
# 좋아요 한적 없으면 post 가능하게 / 있으면 아무기능 없게
def post(self, request, article_id):
article = get_object_or_404(Article, id=article_id)
if request.user in article.likes.all():
article.likes.remove(request.user)
return Response("unlike", status=status.HTTP_200_OK)
else:
article.likes.add(request.user)
return Response("like", status=status.HTTP_200_OK)
# 좋아요를 누르는 함수를 model에서 정의하고 이용했다면 좋아요를 불러올땐? serializers를 통해 불러온다.
# ArticleSerializer에 정의된 likes fields를 이용
class ArticleDetailView(APIView):
# 본인 게시글 가져오기
def get(self, request, article_id):
# article = Article.objects.get(id=article_id)
article = get_object_or_404(Article, id=article_id)
serializer = ArticleSerializer(article)
return Response(serializer.data, status=status.HTTP_200_OK)
[drf에서 follow 기능]
# users APP
- models.py 에 팔로우 필드 추가
class User(AbstractBaseUser):
# ManyToManyField에서 "symmetrical"는 상대방과 대칭적인 관계면 True/ 비대칭 즉, 혼자만 팔로우 할 수 있는 관계라면 False로 선언한다.
followings = models.ManyToManyField('self', symmetrical=False, related_name='followers', blank=True)
# 아무도 팔로우를 하지 않아도 되니까 : blank=True
👉 팔로우 또한 내가 많은 사람들을 팔로우 하거나 다른 사용자들이 나를 팔로우 할 수 있기 때문에 ManyToManyField 사용!
- 기존 serializers.py에 정의된 class 안 followers를 정의해준뒤
class UserprofileSerializer(serializers.ModelSerializer):
# PrimaryKeyRelatedField : id표기 / StringRelatedFiled : email 표기
# followings = serializers.StringRelatedFiled(many=True)
followers = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
- 위에서 정의된 class를 이용해 views.py에서 작업
class ProfileView(APIView):
def get(self, request, user_id):
user = get_object_or_404(User, id=user_id)
serializer = UserprofileSerializer(user)
return Response(serializer.data)
'woncoding > TIL' 카테고리의 다른 글
| TIL | 11.1.화 [AWS] (0) | 2022.11.03 |
|---|---|
| TIL | 10.31.월 [Django : DRF] (0) | 2022.10.31 |
| TIL | 10.27.목 [Django : DRF] (0) | 2022.10.28 |
| TIL | 10.26.수 [Django : DRF] (0) | 2022.10.27 |
| TIL | 10.25.화 [Django : DRF] (0) | 2022.10.25 |