TIL Day 68.

Jen Devver·2024년 5월 22일

내배캠 TIL

목록 보기
75/91

Django 최종 팀 프로젝트

Django Admin 페이지 수정

메뉴 관련 해시태그 필터

  • 문제: 메뉴의 필터를 해시태그로 지정해 주었는데, 모든 유저가 작성한 해시태그의 필터로 동작
  • 해결: MenuAdmin()admin.RelatedOnlyFieldListFilter 를 리스트 필터 옵션에 추가해주어 현재 보이는 메뉴와 관련된 해시태그만 필터에 보이도록 수정
list_filter = [("hashtags", admin.RelatedOnlyFieldListFilter)]

해시태그 페이지 분기 처리

  • 문제: 해시태그 페이지에서 staff일 경우 본인 뿐인 해시태그의 작성자가 디스플레이되고 필터의 경우 해시태그로 지정되어 있어 리스트 조회를 반복하는 것과 같아 사용하지 않는 기능이 표시되고 있음
  • 해결: HashtagAdmin() 에서 get_list_filter()get_list_display()를 사용해서 superuser일 경우 해시태그 작성자가 보이고 그로 필터도 할 수 있도록 했고, staff일 경우 작성자와 해시태그 필터 기능을 모두 삭제함.
    def get_list_filter(self, request):
        if request.user.is_superuser:
            list_filter = ("hashtag_author",)
        else:
            list_filter = ()
        return list_filter
    
    def get_list_display(self, request):
        if request.user.is_superuser:
            list_display = ("hashtag", "hashtag_author", "get_menus")
        else:
            list_display = ("hashtag", "get_menus")
        return list_display

해시태그 중복 처리

  • 문제: 해시태그가 중복 작성 가능 (같은 해시태그가 두 번 이상 생성될 수 있음)
  • 해결: 해시태그가 한 작성자에 대해서는 중복되지 않으면서 전체 테이블에 대해서는 중복이 가능하도록 모델에 UniqueConstraint를 사용해 hashtaghashtag_author의 조합에 대해서 unique할 수 있도록 설정함. 따라서 한 사용자는 중복된 해시태그를 작성할 수 없고 서로 다른 사용자의 경우에는 서로 중복이 되어도 가능함.
    class Meta:
        constraints = [
            models.UniqueConstraint(fields=["hashtag", "hashtag_author"], name="unique_hashtag_author")
        ]

얼굴 인식해 나이 식별 구현

  • 웹캠을 통해 사용자의 얼굴을 인식해 이미지화 한 뒤 gpt-4o를 통해 나이를 판별
  • 새로운 함수를 views.py에 django MTV 형식으로 구현해줌 : 때문에 urls.py 에 URI를 추가해주고 views.py에 FBV 생성해주고 필요한 템플릿 start_order.html과 menu_big.html을 생성
  • start_order()의 경우 주문하기를 누르면 face_recognition()으로 넘어가도록 함
  • face_recognition()은 opencv를 통해 웹캠으로 얼굴이 인식되는 이미지를 저장하면 gpt-4o를 통해 나이를 판별해주는 로직으로 작동함.
  • face.jpg가 계속 저장되어 있으므로 gpt-4o를 통과하고 난 후 삭제해줌.
  • 판별한 나이값을 int 값으로 받아 분기처리를 해줌.
def start_order(request):
    return render(request, 'orders/start_order.html')

def face_recognition(request):
        # 웹캠 열기
    cap = cv2.VideoCapture(0)

    if not cap.isOpened():
        raise Exception("Cannot open Webcam")

    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

    # 프레임 읽기
    while True:
        ret, frame = cap.read()
        print("ret>>>>>>>>>>>", ret)
        print("frame>>>>>>>>>", frame)


        if not ret:
            raise Exception("Cannot read frame from webcam")

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

        if faces.any():
            print("faces>>>>>>>", faces)
            break

    cap.release()

    image_path = "face.jpg"
    print("image_path>>>>>>>>>>", image_path)
    cv2.imwrite(image_path, frame)


    with open(image_path, "rb") as image_file:
        encoded_image = base64.b64encode(image_file.read()).decode('utf-8')
        print("encoded_image>>>>>>>>>>>", encoded_image)
    # base64_image = encoded_image(image_path)
    base64_image = f"data:image/jpeg;base64,{encoded_image}"

    print("base64_image>>>>>>>>>", base64_image)

    headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {OPEN_API_KEY}"
    }

    payload = {
    "model": "gpt-4o",
    "messages": [
        {
        "role": "user",
        "content": [
            {
            "type": "text",
            "text": "Although age can be difficult to predict, please provide an approximate number for how old the person in the photo appears to be. Please consider that Asians tend to look younger than you might think.And Please provide an approximate age in 10-year intervals such as teens, 20s, 30s, 40s, 50s, 60s, 70s, or 80s. Please return the inferred age in the format 'Estimated Age: [inferred age]'."
            },
            {
            "type": "image_url",
            "image_url": {
                "url": base64_image
            }
            }
        ]
        }
    ],
    "max_tokens": 300
    }
    print("api통과??>>>>>>>>>>>>")
    response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)

    try:
        os.remove(image_path)
        print(f"{image_path} 이미지가 삭제되었습니다.")
        
    except FileNotFoundError:
        print(f"{image_path} 이미지를 찾을 수 없습니다.")

    ai_answer = response.json()

    age_message = ai_answer["choices"][0]['message']['content']

    age = age_message.split("Estimated Age: ")[1].strip()
    number = re.findall(r'\d+', age)
    age_number = int(number[0])

    if age_number >= 60:
        return render(request, 'orders/menu_big.html')
    
    return render(request, 'orders/menu.html')

튜터님 멘토링 시간

  • 앞으로 해볼 일
  1. Django Admin 의 staff 페이지를 커스텀해보기
  2. 음성으로 메뉴 선택까지 할 수 있는 기능을 추가해보기
  3. 실버를 타겟으로 하는 만큼 더 확실하게 컨셉을 가져갈 수 있는 프론트엔드 구현해보기: AI가 추천한 음료를 제일 크게 보여주고 관련 해시태그를 가진 다른 음료들은 크기를 작게 구성, 요소들의 글씨, 버튼을 크게 구성하고 상대적으로 심플한 UI를 구성

마지막 깃 머지 되돌리기

실수로 머지를 하면서 원래 머지 하려던 브랜치가 아니라 다른 브랜치에 머지를 했을 때

git reflog 로 한 번 깃 내역을 확인해주고

git reset --hard head^ 로 가장 마지막 내역을 지워줌

git push -f 로 강제 푸쉬해주면 됨

유의해서 사용할 것!! 튜터님이 알려주신 방법이라 그대로 따라한 것이지만 실제로 내가 그냥 사용하려면 신중해야 할 듯

profile
발전 중...

0개의 댓글