๐Ÿฅ”Project/[Project] Threepark

[Capstone Design] 3. ๋ฐฑ์—”๋“œ ๊ตฌํ˜„ - (7) DRF ๊ฐœ๋ฐœ | VIEW

mingyung 2024. 5. 21. 15:14

ํŽธ๋ฆฌํ•œ API์˜ ๊ตฌ์„ฑ์„ ์œ„ํ•ด์„œ Mixins์™€ GenericViewSet์„ ์‚ฌ์šฉํ•œ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

 

class DiaryViewSet(GenericViewSet, # ๋ฏน์Šค์ธ ์‚ฌ์šฉ์„ ์œ„ํ•ด ๊ผญ ์ถ”๊ฐ€
                  mixins.ListModelMixin,#๋ฆฌ์ŠคํŠธ API
                  mixins.CreateModelMixin,#์ƒ์„ฑ API
                  mixins.RetrieveModelMixin,#์กฐํšŒ API
                  mixins.UpdateModelMixin,#์ˆ˜์ • API. ๋ถ€๋ถ„ ์ˆ˜์ •๊ณผ ์ „์ฒด ์ˆ˜์ • ์žˆ์Œ
                  mixins.DestroyModelMixin):#์‚ญ์ œ API

	# ์•„๋ž˜ ํผ๋ฏธ์…˜~์ฟผ๋ฆฌ์…‹์€ ํ•„์ˆ˜ ์ž‘์„ฑ
    permission_classes = [IsOwner]
    serializer_class = DiarySerializer
    queryset = Diary.objects.all()
    """
    ์—ฌ๊ธฐ์— ์ ๋Š” ์ฃผ์„์€ ํ›„์— swagger API๋ฌธ์„œ๋ฅผ ์œ„ํ•œ ๊ฒƒ. ์–ด๋–ค ๋ทฐ์ธ์ง€ ์ž‘์„ฑ.
    ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑ.
    ์ผ๊ธฐ์˜ ๋‚ด์šฉ์— ๋Œ€ํ•œ API
    """
    
    # ์ด ๋ถ€๋ถ„์€ ๋ฏน์Šค์ธ์„ ์‚ฌ์šฉํ•  ๋•Œ ์ฟผ๋ฆฌ๋ฅผ ํ•„ํ„ฐ๋งํ•˜์—ฌ ๋ณธ์ธ์˜ ๋ฐ์ดํ„ฐ๋งŒ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ•œ๊ฒƒ
    def filter_queryset(self,queryset):
        queryset = queryset.filter(user=self.request.user)
        return super().filter_queryset(queryset)
    
    # ์ด ์•„๋ž˜๋กœ ๋ถ€ํ„ฐ ์ถ”๊ฐ€๋กœ ์ปค์Šคํ…€์ด ํ•„์š”ํ•œ ๋ฏน์Šค์ธ๋“ค, ํ•จ์ˆ˜๋“ค์„ ์ž‘์„ฑํ•œ๋‹ค.
    # ์•„๋ž˜๋ถ€๋ถ„์—†์ด๋Š” ๊ธฐ๋ณธ ๋ฏน์Šค์ธ์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•œ๋‹ค

 

๊ธฐ๋ณธ ๋ฏน์Šค์ธ์˜ ํ•จ์ˆ˜๋“ค์€ ์•„๋ž˜ ๊นƒํ—™์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

https://github.com/encode/django-rest-framework/blob/master/rest_framework/mixins.py

 

django-rest-framework/rest_framework/mixins.py at master ยท encode/django-rest-framework

Web APIs for Django. ๐ŸŽธ. Contribute to encode/django-rest-framework development by creating an account on GitHub.

github.com

 

์—ญ์‹œ ๋ทฐ๊ฐ€ ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ํŠน์ˆ˜ํ•œ ๊ฒฝ์šฐ๋งŒ ์‚ดํŽด๋ณด์ž.

 

Follow

ํŒ”๋กœ์ž‰ ๊ธฐ๋Šฅ์„ ๊ธฐ๋ณธ mixins๋“ค์˜ ๊ฐ ๊ธฐ๋Šฅ๋“ค์„ ํ™œ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์˜€๋‹ค. (์•ฝ๊ฐ„ ์•ผ๋งค๋กœ ๊ตฌํ˜„ํ•œ ๋А๋‚Œ.. ํ•˜์ง€๋งŒ ์ž˜ ๋Œ์•„๊ฐ„๋‹ค๋ฉด?)

 

1. permissions์˜ IsOwnerOrReadOnly๋ฅผ ํ†ตํ•ด ํŒ”๋กœ์ž‰์— ์—ฐ๊ด€๋œ ์‚ฌ์šฉ์ž๋งŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

2. filter_queryset์„ ํ†ตํ•ด ์—ฐ๊ด€๋œ ์‚ฌ์šฉ์ž๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

 

๊ฐœ๋ณ„ ํ•จ์ˆ˜๋ณ„ ์—ญํ• 

CREATE : ํŒ”๋กœ์šฐ ์š”์ฒญ

DESTROY: ํŒ”๋กœ์šฐ ์ทจ์†Œ/์‚ญ์ œ

UPDATE: ํŒ”๋กœ์šฐ ํ—ˆ์šฉ

PARTIAL_UPDATE: ํŒ”๋กœ์šฐ ๊ฑฐ์ ˆ

class FollowViewSet(GenericViewSet,
                           mixins.ListModelMixin,
                           mixins.CreateModelMixin,
                           mixins.DestroyModelMixin,
                           mixins.RetrieveModelMixin,
                           mixins.UpdateModelMixin):
    
    permission_classes = [IsOwnerOrReadOnly]
    serializer_class = FollowSerializer
    queryset = Follow.objects.all()
    def filter_queryset(self,queryset):
        queryset = queryset.filter(Q(follower=self.request.user) | Q(following_user=self.request.user))
        
        return super().filter_queryset(queryset)
    '''
    ํŒ”๋กœ์šฐ API
    
    ---
    
    ### id : ํŒ”๋กœ์šฐ ์š”์ฒญ์˜ id
    '''
    @swagger_auto_schema( request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'username': openapi.Schema(type=openapi.TYPE_STRING, description='ํŒ”๋กœ์šฐ ์š”์ฒญํ•  ์œ ์ €์˜ username')
            }
    ))
    def create(self, request, *args, **kwargs):
        '''
        ํŒ”๋กœ์šฐ ์š”์ฒญํ•˜๋Š” API
        
        ---
        
        ### id : ํŒ”๋กœ์šฐ ์š”์ฒญํ•  username
        
        
        ## ์˜ˆ์‹œ request:
        
            {
                "username": "threepark"
            }
            
        ## ์˜ˆ์‹œ response:
            201
            {
                "id": 11,
                "status": "requested",
                "follower": 3,
                "following_user": 1
            }
            
            400
        '''
        # ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ๋ฐ›์Œ
        username = request.data.get('username')
        
        # ๋ฐ›์€ ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๋ฅผ ์ฐพ์Œ
        try:
            following_user = User.objects.get(username=username)
        except User.DoesNotExist:
            return Response({"message": f"User '{username}' does not exist"}, status=status.HTTP_404_NOT_FOUND)
        
        # ํŒ”๋กœ์šฐ ์š”์ฒญ ์ƒ์„ฑ์— ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ ๊ตฌ์„ฑ
        request_data = {
            'follower': request.user.id,
            'following_user': following_user.id,
            'status': Follow.REQUESTED
        }
        
        serializer = self.get_serializer(data=request_data)
        serializer.is_valid(raise_exception=True)
        
        user = self.request.user
        
        followee = serializer.validated_data.get('following_user')
        if followee==user:
            return Response({"message": f"Cannot Follow yourself, {followee.username}."}, status=status.HTTP_400_BAD_REQUEST)
        
        if Follow.objects.filter(follower=user, following_user=followee).exists() | Follow.objects.filter(follower=user, following_user=followee).exists():
            return Response({"message": f"Follow request already sent to {followee.username}."}, status=status.HTTP_400_BAD_REQUEST)
            
       
        follow_request, created = Follow.objects.get_or_create(follower=request.user, following_user=followee, status=Follow.REQUESTED)
       
        serializer = self.get_serializer(follow_request)
        
        
        if created:
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response({"message": f"Follow request already sent to {followee.username}"}, status=status.HTTP_400_BAD_REQUEST)

    
    def destroy(self, request, *args, **kwargs):
        '''
        ํŒ”๋กœ์šฐ ์š”์ฒญ ์‚ญ์ œ/์ทจ์†Œํ•˜๋Š” API
        
        ---
        
        ### id : ํŒ”๋กœ์šฐ ์š”์ฒญ์˜ id
            
        ## ์˜ˆ์‹œ response:
        
            204
            {"message": "Follow request deleted"}
            
        '''
        
        instance = self.get_object()
        self.perform_destroy(instance)
        return Response({"message": "Follow request deleted"}, status=status.HTTP_204_NO_CONTENT)

    @swagger_auto_schema(
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={}
    ))
    def update(self, request, *args, **kwargs):
        '''
        ํŒ”๋กœ์šฐ ์š”์ฒญ ํ—ˆ์šฉํ•˜๋Š” API
        
        ---
        
        ### id : ํŒ”๋กœ์šฐ ์š”์ฒญ์˜ id
        
        ## ์˜ˆ์‹œ response:
        
            200
            {
                "id": 11,
                "status": "accepted",
                "follower": 3,
                "following_user": 1
            }
            401 ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค
        '''
        
        instance = self.get_object()
        
        # ์š”์ฒญ๋ฐ›์€ ์‚ฌ์šฉ์ž๊ฐ€ ํ˜„์žฌ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ
        if instance.following_user != request.user:
            raise PermissionDenied("๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค")
        
        
        instance.status = Follow.ACCEPTED
        instance.save()
        serializer = self.get_serializer(instance)
        return Response(serializer.data, status=status.HTTP_200_OK)

    @swagger_auto_schema(
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={}
    ))
    def partial_update(self, request, *args, **kwargs):
        '''
        ํŒ”๋กœ์šฐ ์š”์ฒญ ๊ฑฐ์ ˆํ•˜๋Š” API
        
        ---
        
        ### id : ํŒ”๋กœ์šฐ ์š”์ฒญ์˜ id
        
        ## ์˜ˆ์‹œ response:
        
            200
            {
                "id": 9,
                "status": "rejected",
                "follower": 2,
                "following_user": 1
            }
                        
        '''
        instance = self.get_object()
        instance.status = Follow.REJECTED
        instance.save()
        serializer = self.get_serializer(instance)
        return Response(serializer.data, status=status.HTTP_200_OK)

 

 

AI ์ž‘์—…์ด ํ•„์š”ํ•œ Viewset๋“ค

์ด ์•„๋ž˜๋Š” API์š”์ฒญ์ด ๋“ค์–ด๊ฐ€๋Š” ์™ธ๋ถ€ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด AI์˜ ์ž‘์—…์ด ์žˆ๋Š” ๋ถ€๋ถ„์— ๋Œ€ํ•œ View์ด๋‹ค.

๋™์ž‘ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

Music

views ์ƒ๋‹จ์— AI ์„œ๋ฒ„๋กœ ์‘์•… ์ถ”์ฒœ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

def request_music_from_flask(content):
    """
    diary content ๋ฅผ ai์„œ๋ฒ„์— ์ „๋‹ฌ, ์Œ์•… ์ถ”์ฒœ ๋ฐ›์•„์˜ด
    """
    flask_url = f'http://{settings.FLASK_URL}:5000/get_music'
    try:
        response = requests.post(flask_url, json={'content': content},verify=False, timeout=50)
        if response.status_code == 200:
            response_data = response.json()
            time.sleep(2)
            return response_data
        else:
            print("Failed to get music from Flask:", response.status_code)
            return None
    except Exception as e:
        print("Error:", e)
        time.sleep(10)
        return None

 

์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์Œ์•… ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๊ณ , ์ผ๊ธฐ์— ์Œ์•… ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค.

 

    def update(self, request,*args, **kwargs):
        """
        diary_music_update ์ผ๊ธฐ์— ๋Œ€ํ•ด ์Œ์•…์„ ์ถ”์ฒœํ•˜๋Š” API
        
        ---
        ### id = ์ผ๊ธฐ ID
        ์ตœ๋Œ€ 15์ดˆ ์†Œ์š” ๊ฐ€๋Šฅ
        ### ์˜ˆ์‹œ request:
        
                {
                    "user": 1,
                }
                
        ### ์˜ˆ์‹œ response:
                200
                {
                    "id": 1,
                    "user": 1,
                    "content": "๋„ˆ๋ฌด ๋‘๊ทผ๊ฑฐ๋ฆฐ๋‹ค! ๊ณผ์—ฐ rds์— ๋‚ด ๋‹ค์ด์–ด๋ฆฌ๊ฐ€ ์ž˜ ์˜ฌ๋ผ๊ฐˆ๊นŒ? ์˜ค๋Š˜ ์ด๊ฒƒ๋งŒ ์„ฑ๊ณตํ•˜๋ฉด ๋„ˆ๋ฌด ์ฆ๊ฑฐ์šด ๋งˆ์Œ์œผ๋กœ ์ž˜ ์ˆ˜ ์žˆ์„๊ฒƒ ๊ฐ™๋‹ค!",
                    "music": {
                        "id": 1,
                        "music_title": "๊ทธ๋Œ€๋งŒ ์žˆ๋‹ค๋ฉด (์—ฌ๋ฆ„๋‚  ์šฐ๋ฆฌ X ๋„ˆ๋“œ์ปค๋„ฅ์…˜ (Nerd Connection))",
                        "artist": "๋„ˆ๋“œ์ปค๋„ฅ์…˜ (Nerd Connection)",
                        "genre": "๋ฐœ๋ผ๋“œ"
                    }
                }
                401 
                400
                {'detail': 'Failed to get similar music from Flask'}
        
        """
        partial = kwargs.pop('partial', True)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        
        print(serializer.data['content'])
        response = request_music_from_flask(serializer.data['content'])
        best_music = response.get('most_similar_song')
        print(best_music)
        similar_songs = response.get('similar_songs')
        print(similar_songs)
        if best_music:
            music, created = Music.objects.get_or_create(music_title=best_music['title'], artist=best_music['artist'], genre=best_music['genre'])
            instance.music = music
            
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)
            
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response({'detail': 'Failed to get similar music from Flask'}, status=status.HTTP_400_BAD_REQUEST)

 

Emotion&Chat

views ์ƒ๋‹จ์— AI ์„œ๋ฒ„๋กœ emotion label ๊ฒ€์ถœ๊ณผ ์‘์› ๋ฌธ๊ตฌ(comment) ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

#views.py์˜ ์ƒ๋‹จ์— AI์„œ๋ฒ„๋กœ ์š”์ฒญ์„ํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›๋Š” ํ•จ์ˆ˜ ์ถ”๊ฐ€

def request_emotion(content):
    """
    ์ผ๊ธฐ ๋‚ด์šฉ์œผ๋กœ emootion label ๊ฒ€์ถœ
    """
    flask_url = f'http://{settings.FLASK_URL}:5000/get_sentiment'
    try:
        
        response = requests.post(flask_url, json={'content': content},verify=False, timeout=50)

        if response.status_code == 200:
            response_data = response.json()
            emotion_label = response_data['emotion_label']
            print("Received emotion_label:", emotion_label)
            time.sleep(2)
            
            return emotion_label
        
        else:
            print("Failed to get emotion from Flask:", response.status_code)
            
            return None
    
    except Exception as e:
        print("Error:", e)
        time.sleep(10)
        
        return None

def request_comment(content):
    """
    ์ผ๊ธฐ ๋‚ด์šฉ์œผ๋กœ ์‘์› ๋ฌธ๊ตฌ ์ƒ์„ฑ
    """
    flask_url = f'http://{settings.FLASK_URL}:5000/get_comment'
    try:
        
        response = requests.post(flask_url, json={'content': content},verify=False, timeout=50)

        if response.status_code == 200:
            response_data = response.json()
            comment = response_data['comment']
            print("Received comment:", comment)
            time.sleep(2)
            
            return comment
        
        else:
            print("Failed to get comment from Flask:", response.status_code)
            
            return None
    
    except Exception as e:
        print("Error:", e)
        time.sleep(10)
        
        return None

 

์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ViewSet๋‚ด๋ถ€์— ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

#ViewSet๋‚ด๋ถ€์— create ์ž‘์„ฑ

    def create(self, request, *args, **kwargs):
        """
        emotion_create ์ผ๊ธฐ ๋‚ด์šฉ์œผ๋กœ ๊ฐ์ •๋ผ๋ฒจ, ์‘์›๋ฌธ๊ตฌ ์ƒ์„ฑ ํ•˜๋Š” API
        
        ---
        ## ์˜ˆ์‹œ request:
        
            {
                'diary' : 2
            }
            
        ## ์˜ˆ์‹œ response:
        
            200
            {
                "id": 2,
                "emotion_label": "๋ถˆ์•ˆ",
                "emotion_prompt": "",
                "chat": " ์ด๋ณ„์€ ์‚ฌ์‹ค์ผ์ง€๋„ ๋ชจ๋ฅด๊ฒ ์–ด์š” ",
                "diary": 2
            }
            
        """
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        diary = serializer.validated_data.get('diary')

        if diary.user != request.user:
            return Response({'error': "Diary does not belong to the current user."}, status=status.HTTP_400_BAD_REQUEST)

        chat = request_comment(diary.content)
        label = request_emotion(diary.content)
        
        existing_emotion = Emotion.objects.filter(diary=diary).first()
        if existing_emotion:
            serializer = self.get_serializer(existing_emotion, data={'chat': chat, 'emotion_label': label}, partial=True)
            serializer.is_valid(raise_exception=True)
            serializer.save(diary=diary, chat=chat, emotion_label = label)
            
        else:
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            serializer.save(diary=diary, chat=chat, emotion_label = label)
        
        return Response(serializer.data, status=status.HTTP_201_CREATED)

 

Image

GPT - ์ด๋ฏธ์ง€ ์ƒ์„ฑ์šฉ ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ

GPT API์™€ ๋ฏธ๋ฆฌ ์ •์˜ํ•œ GPT ํ”„๋กฌํ”„ํŠธ๋ฅผ ํ•ฉํ•˜์—ฌ GPT์— ์ด๋ฏธ์ง€ ์ƒ์„ฑ์šฉ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

from django.conf import settings 
import openai

with open(f"{settings.BASE_DIR}/ai/genTextBase.txt", 'r', encoding='utf-8') as file:
    base_text = ''.join(file.readlines())

    api_key = settings.OPENAI_API_KEY
    openai.api_key=api_key
    
def get_prompt(content):
    """
    ์ผ๊ธฐ ๋‚ด์šฉ์„ ์ž…๋ ฅ๋ฐ›์•„ ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ
    """
    completion = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": f"{base_text} {content.strip()}"},]
    )
    generated_text = completion["choices"][0]["message"]["content"]
    output_text=generated_text.split('\n')
    pre_text = "(masterpiece,detailed), (Oil Painting:1.3), (Impressionism:1.3) ,(oil painting with brush strokes:1.2), (looking away:1.1), "
    prompts = [pre_text+v for v in output_text if v]
    return prompts

 

Flask&AI์„œ๋ฒ„ - ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์š”์ฒญ

์ด๋ฏธ์ง€ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ „๋‹ฌํ•ด AI์„œ๋ฒ„์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ด๋ฏธ์ง€ url์„ ์‘๋‹ต์œผ๋กœ ๋ฐ›๋Š”๋‹ค.

def request_image_from_flask(prompt):
    """
    ์ƒ์„ฑ๋œ prompt๋กœ ์ด๋ฏธ์ง€ ์ƒ์„ฑ
    """
    flask_url = f'http://{settings.FLASK_URL}:5000/get_image'
    
    try:
        # HTTP POST ์š”์ฒญ์œผ๋กœ prompt๋ฅผ Flask์— ์ „์†ก
        response = requests.post(flask_url, json={'prompt': prompt},verify=False, timeout=150)
        # ์‘๋‹ต ํ™•์ธ
        if response.status_code == 200:
            # ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์„ฑ๊ณต
            response_data = response.json()
            image_url = response_data['image_url']
            print("Received image url:", image_url)
            time.sleep(2)
            return image_url
        else:
            # ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์‹คํŒจ
            print("Failed to get image from Flask:", response.status_code)
            return None
    except Exception as e:
        print("Error:", e)
        time.sleep(10)
        return None

 

Viewset - createํ•จ์ˆ˜ ์ž‘์„ฑ

์œ„์—์„œ ์ž‘์„ฑํ•œ ํ•จ์ˆ˜๋“ค์„ ํ†ตํ•ด ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ „๋‹ฌ๋ฐ›์€ url์„ ํ†ตํ•ด ์ด๋ฏธ์ง€ ์‹œ๋ฆฌ์–ผ๋ผ์ด์ € ์ƒ์„ฑ

    def create(self, request, *args, **kwargs):
        
        '''
        ์ด๋ฏธ์ง€ ์ƒ์„ฑ API
        
        ---
        
        ### ์‘๋‹ต์— ์ตœ๋Œ€ 40์ดˆ ์†Œ์š” ๊ฐ€๋Šฅ 
        ## ์˜ˆ์‹œ request:
        
            {
                'diary' : 1
            }
            
        ## ์˜ˆ์‹œ response:
        
            201
            {
                  "id": 70,
                    "created_at": "2024-05-02T13:04:10.208658+09:00",
                    "image_url": "https://๋ฒ„ํ‚ท์ฃผ์†Œ/images/826cb58e-46a3-41fc-9699-bc2eccdc1355.jpg",
                    "image_prompt": "(masterpiece,detailed), (Oil Painting:1.3), (Impressionism:1.3) ,(oil painting with brush strokes:1.2), (looking away:1.1), a girl in a traditional Korean hanbok, cherry blossom background, soft pastel colors, Korean artist reference, (ethereal:1.2), (delicate details:1.3), (dreamy atmosphere:1.25)",
                    "diary": 1
            }
            400
            {
                'error': "Failed to get image from Flask" ์ด ๊ฒฝ์šฐ AI ์„œ๋ฒ„๊ฐ€ ๊บผ์ ธ์žˆ์„๋•Œ์ž„
            }
            400
            {
                'error': "Error uploading image: {str(e)}"
            }
            401 
            403 
        '''

        try:
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            
            diary = serializer.validated_data.get('diary')
            image_prompt = get_prompt(diary.content)[0]
            image_url = request_image_from_flask(image_prompt)
            
            if not image_url:
                return Response({'error': "Failed to get image from Flask"}, status=status.HTTP_400_BAD_REQUEST)
            
            new_image = Image.objects.get_or_create(diary=diary, image_url=image_url, image_prompt=image_prompt)
            serializer.validated_data['diary'] = diary
            serializer.validated_data['image_url'] = image_url
            serializer.validated_data['image_prompt'] = image_prompt
            serializer.save()
            
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        
        except Exception as e:
                return Response({'error': f"Error uploading image: {str(e)}"}, status=status.HTTP_400_BAD_REQUEST)