AI웹 개발자 과정 공부 (팀스파르타)/프로젝트

24.06.12_TIL ( 팀 프로젝트 : AI NOST Django ) _ 14. db데이터 지우기, deepl 트러블 슈팅, User권한 확인, 사용자 아니면 delete버튼 안보이기

티아(tia) 2024. 6. 12. 09:34
728x90


[ 세번째 프로젝트 ] 

 
 

AI를 이용한 소설 사이트를 만들어 보자.

 
 
 
 
++  팀 스로젝트로 팀과의 협업이 중요하다.
++  장고 공식 문서는 항상 확인하기 

https://docs.djangoproject.com/en/4.2/

 

++ 랭체인 공식 문서

https://www.langchain.com/

 

++ 리액트 공식문서

https://ko.legacy.reactjs.org/  # 한국어
https://ko.react.dev/


 
https://github.com/1489ehdghks/NOST.git

 

GitHub - 1489ehdghks/NOST

Contribute to 1489ehdghks/NOST development by creating an account on GitHub.

github.com

 

 

 

 

 

 

 

 

 

 

 

1.  디비에 남아있는 회원정보를 지워보자

 

sell 로 해서 지우는 방법이 있다.

 

python manage.py shell

 

 

 

특정 유저한테서 책만들기 shell로 하려고 했는데 안되네ㅜㅜ

python manage.py shell

from accounts.models import User
from books.models import Book  //모델에 내 앱모델이름

 

 

 

 

 

 

 

2.  유저 권한 확인

 

유저 이메일 인증해서 들어가서 잘 되는지 확인한다.

연결해놓은 것이 토큰값을 확인하고 되는 것을 볼 수 있다.

 

처음 Get 으로 된것도 못가져와서 다음과 같은 권한으로 바꾸었다.

from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly

permission_classes = [IsAuthenticatedOrReadOnly]

 

 

좋아요와 별점이 사용자가 하는데도 되지 않아서 백엔드에서 수정하였다.

like_bool 을 없애고 if 문을 하나 없애었다.

 

그리고 별점을 소수점 한자리까지만 하기 위해서 다음과 같이 수정

class BookSerializer(serializers.ModelSerializer):
    average_rating = serializers.SerializerMethodField()
    user_nickname = serializers.SerializerMethodField()
    chapters = ChapterSerializer(many=True, read_only=True)

    class Meta:
        model = Book
        fields = "__all__"

    def get_average_rating(self, book):
        avg_rating = Rating.objects.filter(book=book).aggregate(avg_rating=Avg("rating"))["avg_rating"]
        return round(avg_rating, 1) if avg_rating is not None else None

 

소수점 한자리까지만 나오기가 된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

3.  deepl 트러블 슈팅

 

번역AI 프로그램인 deep_L 을 실행하는데 오류가 떴다.

 

AttributeError: 'Translator' object has no attribute 'translate_text'
[07/Jun/2024 12:05:23] "POST /api/books/ HTTP/1.1" 500 114084

 

이런 오류 메세지....

왜 없다고 하는지 모르겠다.

books/ deepl_translation.py


import deepl
from django.conf import settings

# 요약 내용 지정 언어로 번역
def translate_summary(content, language) :
    
    auth_key = settings.DEEPL_API_KEY
    translator = deepl.Translator(auth_key)

    if isinstance(content,dict) : #data 값이 dict 형태일때 번역
        translated_data = {}
        for key,value in content.items() :
            result = translator.translate_text(value, target_lang=language)
            translated_data[key] = result.text
        return translated_data
    elif isinstance(content,str) : #data 값이 text 형태일때 번역
        result = translator.translate_text(content, target_lang=language)
        return result.text

 

멀쩡히 있는데 안나온다.

 

deepl 과 deepl.py를 두개 설치해 주셨다고 했는데

이게 버전차이로 충돌이 나서 두개를 한꺼번에 가져오지 못하고

중간에 가져오는 것을 다 못가져와서  translate_text 이걸 못가져온 거였다.ㅠㅠ

이걸로 6시간을 끙끙.... 누구는 되고 누구는 안되고.... 아마 가져오고 안가져오고 랜덤이었던것 같다.

 

 

pip uninstall deepl
pip uninstall deepl-py

 

그래서 버전을 다 삭제해주고 다시 deepl만 깔아서 코드를 조금 수정해주어야한다.

pip install deepl

 

 

새로운 프론트엔드 파일도 받아와서 잘 연결되어 생성되는 것을 확인할 수 있다....ㅠㅠ

아이고... 정말 이거 6시간 걸렸는데 다 정리되서 설명 써놓으니까 몇줄안에 끝나다니ㅜㅜ 억울하다...

 

 

 

 

 

 

 

 

 

 

4. 사용자 아니면 delete버튼 안보이기

src/ pages/ widgets/ bookdetail.jsx 수정하기

import useAuthStore from '../../shared/store/AuthStore'; // useAuthStore 불러오기

...

const BookDetail = () => {
 
 ...
 
  const { userId: currentUserId } = useAuthStore(); // 현재 사용자 ID 가져오기


  useEffect(() => {
    axios.get(`http://127.0.0.1:8000/api/books/${id}/`)
      .then(response => {
        setBookData(response.data);
        console.log('data : ', response.data);
      })
      .catch(error => {
        console.error('Error fetching book data:', error);
      });

    axios.get(`http://127.0.0.1:8000/api/books/${id}/comments/`)
      .then(response => {
        setComments(response.data || []);
      })
      .catch(error => {
        console.error('Error fetching comments:', error);
      });
  }, [id]);

  const handleDeleteBook = async () => {
    try {
      await axiosInstance.delete(`http://127.0.0.1:8000/api/books/${id}/`);
      // 삭제 성공 시, 메인 페이지로 이동
      navigate('/main');
    } catch (error) {
      console.error('Error deleting book:', error);
    }
  };
  
...

  return (
    
    ...
    
              {bookData.user_id === currentUserId && ( // 현재 사용자와 책 작성자 비교
                <button
                  style={buttonStyle}
                  onClick={handleDeleteBook}
                >
                  Delete Book
                </button>
              )}
            ...
            
    </div>
  );
};

export default BookDetail;

 

 

comment 부분도 같이 수정해준다.

import useAuthStore from '../../shared/store/AuthStore'; // useAuthStore 불러오기


const BookComment = ({ bookId, comments, setComments, currentTheme }) => {

...

  const { userId: currentUserId } = useAuthStore(); // 현재 사용자 ID 가져오기

...


  return (
    <div className="comment-box" style={{ color: currentTheme.textColor }}>
      <h2>Comment Box</h2>
      <div className="comments">
        {comments.slice(0, visibleComments).map((comment) => (
          <div className="comment" key={comment.id}>
            <div className="comment-avatar" style={{ backgroundColor: currentTheme.buttonBackgroundColor, color: currentTheme.buttonTextColor }}>
              {comment.user_nickname.charAt(0).toUpperCase()}
            </div>
            <div className="comment-content">
              <p>{comment.content}</p>
              <p style={{ color: currentTheme.sidebarBg }}>{comment.user_nickname}
                <small> | {new Date(comment.created_at).toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' })}</small>
              </p>
              <div>
                {comment.user_id === currentUserId && ( // 현재 사용자와 댓글 작성자 비교
                  <>
                    <button style={buttonStyle} onClick={() => { setEditingCommentId(comment.id); setUpdatedContent(comment.content); }}>Edit</button>
                    <button style={buttonStyle} onClick={() => handleDeleteComment(comment.id)}>Delete</button>
                    {editingCommentId === comment.id && (
                      <div>
                        <textarea value={updatedContent}
                          onChange={(e) => setUpdatedContent(e.target.value)}></textarea>
                        <button style={buttonStyle} onClick={() => handleEditComment(comment.id, updatedContent)}>Save</button>
                        <button style={buttonStyle} onClick={() => setEditingCommentId(null)}>Cancel</button>
                      </div>
                    )}
                  </>
                )}
              </div>
            </div>
          </div>
        ))}
        
        
        ...
        
  );
};

export default BookComment;

 

 

 

 

 

반응형