_won_
wonprogrammer
_won_
전체 방문자
오늘
어제
  • 분류 전체보기
    • woncoding
      • TIL
      • WIL
    • source Code
      • Python
      • Programmers
      • BAEKJOON

블로그 메뉴

  • 방명록

티스토리

Github · Wonprogrammer
hELLO · Designed By 정상우.
_won_

wonprogrammer

woncoding/TIL

TIL | 10.28.금 [Django : DRF]

2022. 10. 31. 16:43

- 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

  1. serializer.py 에서 Article model object 를 모두 받아온다
  2. 받아온 뒤 views.py에서 받아온 objects를 serializer화 시켜주고
  3. 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
    'woncoding/TIL' 카테고리의 다른 글
    • TIL | 11.1.화 [AWS]
    • TIL | 10.31.월 [Django : DRF]
    • TIL | 10.27.목 [Django : DRF]
    • TIL | 10.26.수 [Django : DRF]
    _won_
    _won_
    Coding Practice blog

    티스토리툴바