내일배움캠프 - My Little Beer 개발일지

Dongwoo Kim·2022년 6월 16일
0

스파르타 코딩클럽

내일배움캠프 AI 웹개발자양성과정 2회차

추천시스템 팀 프로젝트 개발일지

0. 프로젝트 정보

1) 프로젝트 명

MLB - My Little Beer : 맥주 추천 웹서비스

2) 기간

2022.06.02-13

3) 프로젝트 목표

  1. django를 이용한 프로젝트 만들기
  2. 추천시스템 적용시켜보기
  3. CRUD 숙련

4) 팀 정보

  • 팀명 : 판타스틱4
  • 팀원 : 김동우, 김진수, 최민기, 이윤지

5) 역할 분담

김동우 : 사용자가 선호하는 맥주 특징을 고르면 그것과 비슷한 유형의 맥주를 추천 (저장가능)

김진수 : 로그인 / 회원가입 / 회원수정 / 회원탈퇴

이윤지 : 저장된 추천 받은 검색 기록 리스팅 / 삭제 페이지

최민기 : 맥주 정보를 볼 수 있는 리스팅 페이지 (조건을 걸어서 종류별로 리스팅할 수 있게)

1. 데이터셋 & 추천시스템 알고리즘

1) 데이터셋

2) 추천시스테 알고리즘

  • 아이템기반 협업 필터링
    1. 사용자가 좋아하는 맥주 특징을 입력
    2. 사용자가 입력한 맥주 특징과 유사도 계산
    for 맥주 in 77종류의 맥주별 :
    	for 특징 in 7개의 특징별:
    		사용자가 입력한 맥주 특징과 유사도 계산
    		특징별 점수 총합 += 유사도
    	맥주 별 점수 총합 리스트에 append
    맥주 별 점수 총합 리스트에서 최대값인 맥주를 추천 맥주로 선정

2. 추천시스템 기능 구현

1) 리스트 파싱 기능

: 데이터셋의 문자열타입의 리스트를 리스트 타입으로 파싱

# 문자열 형태의 맥주 특징을 리스트 형태로 파싱하는 함수
# array_str : 문자열 형태의 맥주 특성
# return : 리스트 형태의 맥주 특성
def list_parser(array_str):
    try:
        temp = array_str[1:-1].split(', ')
        for i in range(len(temp)):
            temp[i] = temp[i][1:-1]
    except:
        temp = array_str
    return temp

2) 자카드 유사도

: 맥주의 특징에 대한 유사도를 측정하기위한 자카드 유사도 알고리즘

# 두 리스트의 유사도를 측정하는 자카드 유사도 함수
# list_1, list_2 : 유사도를 측정하는 두 리스트
# return : 두 리스트의 유사도 비율
def jaccard_similarity(list_1, list_2):
    union = list(set(list_1) | set(list_2))
    intersection = list(set(list_1) & set(list_2))
    return len(intersection) / len(union)

3) 추천 기능 함수

: 사용자가 입력한 맥주의 특징들을 받아 DB의 맥주 데이터들과 유사도를 측정하고 가장 유사도가 높은 맥주를 return하는 함수

# 입력받은 맥주 특성과 유사도가 비슷한 맥주를 찾는 함수
# user_beer : 유저가 선호하는 맥주 특징
# return : 가장 유사도가 높은 맥주, 유사도
def find_favorite_beer(user_beer):
    features = ['style', 'category', 'aroma', 'flavor', 'season', 'paring_food', 'body']
    base_beer = user_beer
    beers = Beer.objects.all()
    scores = {}

    # 맥주 별
    for beer in beers:
        score = 0
        for i, feature in enumerate(features):
            # style, category : 같은 지 확인
            if i < 2:
                if base_beer[i] == getattr(beer, feature):
                    ratio = 0.3
                else:
                    ratio = 0
            # 나머지 특징 : 문자열 형태를 리스트 형태로 바꾼뒤 자카드 유사도로 측정
            else:
                list_feature = list_parser(getattr(beer, feature))
                ratio = jaccard_similarity(base_beer[i], list_feature)

            score += 10 * ratio

        scores[beer.name] = round(score, 2)

    max_beer = max(scores, key=scores.get)

    return max_beer, scores[max_beer]

3. API 구현 (recommend/views.py)

def home(request):
    if request.method == 'GET':
        user = request.user.is_authenticated
        if user:
            return redirect('/recommend')
        else:
            return redirect('/sign-in')


@csrf_exempt
def recommend(request):
    if request.method == 'GET':
        # create_db_beer()
        # beer_rating_slice()
        user = request.user.is_authenticated
        if user:
            return render(request, 'recommend/index.html')
        else:
            return redirect('/sign-in')
    elif request.method == 'POST':
        style = request.POST.get('style', '')
        category = request.POST.get('category', '')
        aroma = request.POST.getlist('aroma')
        flavor = request.POST.getlist('flavor')
        season = request.POST.getlist('season')
        food = request.POST.getlist('food')
        body = request.POST.getlist('body')

        user_beer = [style, category, aroma, flavor, season, food, body]
        favorite_beer, score = find_favorite_beer(user_beer)

        favorite_beer = Beer.objects.get(name=favorite_beer)

        user = request.user

        history = History.objects.create(beer=favorite_beer, user=user)
        history.save()

        return render(request, 'recommend/result.html', {'beer': favorite_beer,
                                                         'score': score})

4. 배포 관련 (settings.py)

0) key_info

: SECRET KEY, RDS, S3 등 개인접근정보 보관파일 (git에 올리지않고 따로 보관)

from .key_info import *

1) RDS

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mylittlebeer',
        'USER': DATABASE_USER,
        'PASSWORD': DATABASE_PASSWORD,
        'HOST': DATABASE_HOST,
        'PORT': '3306',
        'OPTIONS': {
            'init_command': 'SET sql_mode="STRICT_TRANS_TABLES"'
        }
    }
}

2) S3

AWS_ACCESS_KEY_ID = MY_AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY = MY_AWS_SECRET_ACCESS_KEY

AWS_REGION = 'ap-northeast-2'
AWS_STORAGE_BUCKET_NAME = 'mylittlebeer'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.%s.amazonaws.com' % (
    AWS_STORAGE_BUCKET_NAME, AWS_REGION)
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}
AWS_DEFAULT_ACL = 'public-read'
AWS_LOCATION = 'static'
STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

DEFAULT_FILE_STORAGE = 'config.asset_storage.MediaStorage'

5. templates 파일 작성

1) templates/base.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <!-- jQuery, Bootstrap JS -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
            crossorigin="anonymous"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>

    <!-- google font -->
    <link rel="preconnect" href="https://fonts.googleapis.com"/>
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
    <link           href="https://fonts.googleapis.com/css2?family=Nanum+Gothic&display=swap"
            rel="stylesheet"
    />

    <!-- css, js -->
    <link rel="stylesheet" href="{% static 'css/common.css' %}">
    <script defer src="{% static 'js/common.js' %}"></script>

    <!-- 참조할 css, js -->
    {% block link %}
    {% endblock link %}

    <!-- 페이지별 타이틀 -->
    {% block title %}
        <title>MyLittleBeer_rating</title>
    {% endblock title %}

</head>
<!-- 해더 -->
<div class="header">
    <!--    로고-->
    <div class="header_body">
        <a href="/static"><img class="logo" src="{% static 'images/logo.png' %}"/></a>
        <!--        타이틀-->
        <div class="container">
            <div class="neon">My Pick!</div>
        </div>
        <!--        유저정보-->
        <div class="user_info">
            <span style="font-weight: bold" id="user_name">{{ user.username }}</span> <br/>
            <span id="user_email">{{ user.email }}</span> <br/>
            <button id="logout_btn" onclick="location.href='/logout'">로그아웃</button>
            <button id="logout_btn" onclick="location.href='/update'">회원 수정</button>
            <button id="logout_btn" onclick="location.href='/delete'">회원 탈퇴</button>
        </div>
    </div>
</div>

<body class="team_color">
  <div class="main_body">
      <!--  -->
      {% block content %}
      {% endblock content %}
  </div>
</body>
</html>

2) templates/recommend/index.html

{% extends 'base.html' %}
{% load static %}

{% block link %}
    <link rel="stylesheet" href="{% static 'css/recommend.css' %}">
    <script defer src="{% static 'js/recommend.js' %}"></script>
{% endblock link %}

{% block title %}
    <title>My Little Beer</title>
{% endblock title %}

{% block content %}
    <div class="recommend_message_box">
        <div class="recommend_title">나만의 맥주 찾기!</div>
        좋아하는 맥주의 특징을 골라 나에게 맞는 맥주를 찾아보세요!
    </div>

    <div class="beer_info">
        <form method="post" action="/recommend/">
            {% csrf_token %}
            <div class="beer_style">
                <div class="feature_title">1. 스타일</div>
                <select class="feature_style" name="style">
                    <option value="Belgian Ale - Dark / Amber">Belgian Ale - Dark / Amber</option>
                    <option value="Dark Lager - Dunkel / Tmavý">Dark Lager - Dunkel / Tmavý</option>
                    <option value="Radler / Shandy">Radler / Shandy</option>
                    <option value="Pilsener - Imperial">Pilsener - Imperial</option>
                    <option value="Flavored - Other">Flavored - Other</option>

                    <option value="Flavored - Fruit">Flavored - Fruit</option>
                    <option value="Zwickelbier / Kellerbier / Landbier">Zwickelbier / Kellerbier / Landbier</option>
                    <option value="Pale Lager - International / Premium">Pale Lager - International / Premium</option>
                    <option value="IPA">IPA</option>
                    <option value="Pilsener - Bohemian / Czech">Pilsener - Bohemian / Czech</option>

                    <option value="Märzen / Oktoberfest Bier">Märzen / Oktoberfest Bier</option>
                    <option value="Stout - Dry / Irish">Stout - Dry / Irish</option>
                    <option value="Pale Ale - American (APA)">Pale Ale - American (APA)</option>
                    <option value="Weissbier - Dunkelweizen">Weissbier - Dunkelweizen</option>
                    <option value="Dark Lager - International / Premium">Dark Lager - International / Premium</option>

                    <option value="Witbier / Belgian White Ale">Witbier / Belgian White Ale</option>
                    <option value="Amber Lager - International / Vienna">Amber Lager - International / Vienna</option>
                    <option value="Pilsener / Pils / Pilsner">Pilsener / Pils / Pilsner</option>
                    <option value="Porter">Porter</option>
                    <option value="Wheat Ale">Wheat Ale</option>

                    <option value="Stout">Stout</option>
                    <option value="Pale Ale - English">Pale Ale - English</option>
                    <option value="Weissbier - Hefeweizen">Weissbier - Hefeweizen</option>
                    <option value="Pale Lager - American">Pale Lager - American</option>
                </select>
            </div>

            <div class="beer_style">
                <div class="feature_title">2. 카테고리</div>
                <select class="feature_style" name="category">
                    <option value="벨기에 맥주">벨기에 맥주</option>
                    <option value="미국-크래프트 맥주">미국-크래프트 맥주</option>
                    <option value="컨티넨털 에일/바이스비어/에일-라거하이브리드">컨티넨털 에일/바이스비어/에일-라거하이브리드</option>
                    <option value="라거">라거</option>
                    <option value="영국-아일랜드 에일">영국-아일랜드 에일</option>
                    <option value="기타">기타</option>
                </select>
            </div>

            <div class="beer_aroma">
                <div class="feature_title">3. 향 <span>다중 선택 가능</span></div>
                <div class="beer_checkbox">
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="풀잎향">풀잎향</div>
                        <div><input type="checkbox" name="aroma" value="약한 스컹스 향">약한 스컹스 향</div>
                        <div><input type="checkbox" name="aroma" value="소나무향">소나무향</div>
                        <div><input type="checkbox" name="aroma" value="쌀 향">쌀 향</div>
                        <div><input type="checkbox" name="aroma" value="스파이시한 향">스파이시한 향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="약한 빵 향">약한 빵 향</div>
                        <div><input type="checkbox" name="aroma" value="달콤한 향">달콤한 향</div>
                        <div><input type="checkbox" name="aroma" value="맥아 로스팅향">맥아 로스팅향</div>
                        <div><input type="checkbox" name="aroma" value="쿠키향">쿠키향</div>
                        <div><input type="checkbox" name="aroma" value="강한 향">강한 향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="로스팅 보리향">로스팅 보리향</div>
                        <div><input type="checkbox" name="aroma" value="오렌지">오렌지 향</div>
                        <div><input type="checkbox" name="aroma" value="거친 맥아향">거친 맥아향</div>
                        <div><input type="checkbox" name="aroma" value="희미한 옥수수향">희미한 옥수수향</div>
                        <div><input type="checkbox" name="aroma" value="순한 고수향">순한 고수향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="밀 향">밀 향</div>
                        <div><input type="checkbox" name="aroma" value="깔끔한 맥아향">깔끔한 맥아향</div>
                        <div><input type="checkbox" name="aroma" value="단맛">단맛</div>
                        <div><input type="checkbox" name="aroma" value="풀향">풀향</div>
                        <div><input type="checkbox" name="aroma" value="민트향">민트향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="사츠홉향">사츠홉향</div>
                        <div><input type="checkbox" name="aroma" value="캐러멜향">캐러멜향</div>
                        <div><input type="checkbox" name="aroma" value="과일향">과일향</div>
                        <div><input type="checkbox" name="aroma" value="고수">고수</div>
                        <div><input type="checkbox" name="aroma" value="꽃 향기">꽃 향기</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="후추향">후추향</div>
                        <div><input type="checkbox" name="aroma" value="볶은 맥아향">볶은 맥아향</div>
                        <div><input type="checkbox" name="aroma" value="꽃향기">꽃향기</div>
                        <div><input type="checkbox" name="aroma" value="노블 홉향">노블 홉향</div>
                        <div><input type="checkbox" name="aroma" value="빵 향">빵 향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="창백한 맥아향">창백한 맥아향</div>
                        <div><input type="checkbox" name="aroma" value="약한 캐라멜 멕아향">약한 캐라멜 멕아향</div>
                        <div><input type="checkbox" name="aroma" value="홉향">홉 향</div>
                        <div><input type="checkbox" name="aroma" value="스컹크 향">스컹크 향</div>
                        <div><input type="checkbox" name="aroma" value="맥아향">맥아향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="달콤한 맥아향">달콤한 맥아향</div>
                        <div><input type="checkbox" name="aroma" value="허브향">허브향</div>
                        <div><input type="checkbox" name="aroma" value="풀잎 향">풀잎 향</div>
                        <div><input type="checkbox" name="aroma" value="약간의 과일향">약간의 과일향</div>
                        <div><input type="checkbox" name="aroma" value="가벼운 스컹스 향">가벼운 스컹스 향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="라즈베리향">라즈베리향</div>
                        <div><input type="checkbox" name="aroma" value="스파이시한 효모향">스파이시한 효모향</div>
                        <div><input type="checkbox" name="aroma" value="약한 스컹크 향">약한 스컹크 향</div>
                        <div><input type="checkbox" name="aroma" value="매운 향">매운 향</div>
                        <div><input type="checkbox" name="aroma" value="레몬향">레몬향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="은은한 맥아향">은은한 맥아향</div>
                        <div><input type="checkbox" name="aroma" value="초콜렛 향">초콜렛 향</div>
                        <div><input type="checkbox" name="aroma" value="자몽향">자몽향</div>
                        <div><input type="checkbox" name="aroma" value="고소한 맥아향">고소한 맥아향</div>
                        <div><input type="checkbox" name="aroma" value="가벼운 곡물향">가벼운 곡물향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="깔끔한 맥아향">깔끔한 맥아향</div>
                        <div><input type="checkbox" name="aroma" value="가벼운 낱알 몰트 향">가벼운 낱알 몰트 향</div>
                        <div><input type="checkbox" name="aroma" value="플로랄 홉향">플로랄 홉향</div>
                        <div><input type="checkbox" name="aroma" value="멕아 로스팅향">멕아 로스팅향</div>
                        <div><input type="checkbox" name="aroma" value="바나나 향">바나나 향</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="aroma" value="옥수수 향">옥수수 향</div>
                        <div><input type="checkbox" name="aroma" value="북미 홉향">북미 홉향</div>
                        <div><input type="checkbox" name="aroma" value="약한 과일향">약한 과일향</div>
                        <div><input type="checkbox" name="aroma" value="가벼운 향">가벼운 향</div>
                        <div><input type="checkbox" name="aroma" value="커피향">커피향</div>
                    </div>
                </div>
            </div>

            <div class="beer_aroma">
                <div class="feature_title">4. 맛 <span>다중 선택 가능</span></div>
                <div class="beer_checkbox">
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" value="쌉쌀한 끝맛">쌉쌀한 끝맛</div>
                        <div><input type="checkbox" value="드라이한 크림 풍미">드라이한 크림 풍미</div>
                        <div><input type="checkbox" value="강한 쓴맛">강한 쓴맛</div>
                        <div><input type="checkbox" value="부드러움">부드러움</div>
                        <div><input type="checkbox" value="홉 풍미 거의 없음">홉 풍미 거의 없음</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="약간 쌉쌀함">약간 쌉쌀함</div>
                        <div><input type="checkbox" name="flavor" value="약한 쓴맛">약한 쓴맛</div>
                        <div><input type="checkbox" name="flavor" value="탄산수">탄산수</div>
                        <div><input type="checkbox" name="flavor" value="약한 떫은 맛">약한 떫은 맛</div>
                        <div><input type="checkbox" name="flavor" value="역겨움">역겨움</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="밀크세이크 질감">밀크세이크 질감</div>
                        <div><input type="checkbox" name="flavor" value="깔끔한 맥아 풍미">깔끔한 맥아 풍미</div>
                        <div><input type="checkbox" name="flavor" value="시큼한 풍미">시큼한 풍미</div>
                        <div><input type="checkbox" name="flavor" value="건포도">건포도</div>
                        <div><input type="checkbox" name="flavor" value="고도의 탄산">고도의 탄산</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="커피">커피</div>
                        <div><input type="checkbox" name="flavor" value="섬세한 맥아 풍미">섬세한 맥아 풍미</div>
                        <div><input type="checkbox" name="flavor" value="로스팅 보리향">로스팅 보리향</div>
                        <div><input type="checkbox" name="flavor" value="구운 풍미">구운 풍미</div>
                        <div><input type="checkbox" name="flavor" value="사츠 홉의 풍미">사츠 홉의 풍미</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="청량한 끝맛">청량한 끝맛</div>
                        <div><input type="checkbox" name="flavor" value="맥아 풍미">맥아 풍미</div>
                        <div><input type="checkbox" name="flavor" value="청량함">청량함</div>
                        <div><input type="checkbox" name="flavor" value="깔끔한 쓴맛">깔끔한 쓴맛</div>
                        <div><input type="checkbox" name="flavor" value="강렬함">강렬함</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="데킬라맛">데킬라맛</div>
                        <div><input type="checkbox" name="flavor" value="달콤한 쿠기 풍미">달콤한 쿠키 풍미</div>
                        <div><input type="checkbox" name="flavor" value="가벼운 곡물 풍미">가벼운 곡물 풍미</div>
                        <div><input type="checkbox" name="flavor" value="초콜렛">초콜렛</div>
                        <div><input type="checkbox" name="flavor" value="단맛 거의 없음">단맛 거의 없음</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="크리미한 맥아 풍미">크리미한 맥아 풍미</div>
                        <div><input type="checkbox" name="flavor" value="캐러멜">캐러멜</div>
                        <div><input type="checkbox" name="flavor" value="생강 힌트">생강 힌트</div>
                        <div><input type="checkbox" name="flavor" value="가벼운 맥아 풍미">가벼운 맥아 풍미</div>
                        <div><input type="checkbox" name="flavor" value="보조 맥아 힌트">보조 맥아 힌트</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="약한 홉 풍미">약한 홉 풍미</div>
                        <div><input type="checkbox" name="flavor" value="견고한 쓴맛">견고한 쓴맛</div>
                        <div><input type="checkbox" name="flavor" value="상큼함">상큼함</div>
                        <div><input type="checkbox" name="flavor" value="낮은 알코올">낮은 알코올</div>
                        <div><input type="checkbox" name="flavor" value="옥수수 맛">옥수수 맛</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="달콤함">달콤함</div>
                        <div><input type="checkbox" name="flavor" value="약간 크리미">약간 크리미</div>
                        <div><input type="checkbox" name="flavor" value="쌉쌀한 풍미">쌉쌀한 풍미</div>
                        <div><input type="checkbox" name="flavor" value="쓴 맛">쓴 맛</div>
                        <div><input type="checkbox" name="flavor" value="섬세한">섬세한</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="약한 캐러멜">약한 캐러멜</div>
                        <div><input type="checkbox" name="flavor" value="할러타우 홉">할러타우 홉</div>
                        <div><input type="checkbox" name="flavor" value="단 맛">단 맛</div>
                        <div><input type="checkbox" name="flavor" value="상쾌함">상쾌함</div>
                        <div><input type="checkbox" name="flavor" value="쓴 맛">쓴 맛</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="과일 풍미">과일 풍미</div>
                        <div><input type="checkbox" name="flavor" value="견과류 풍미">견과류 풍미</div>
                        <div><input type="checkbox" name="flavor" value="사과맛">사과맛</div>
                        <div><input type="checkbox" name="flavor" value="옥수수 단맛">옥수수 단맛</div>
                        <div><input type="checkbox" name="flavor" value="섬세함">섬세함</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="순함">순함</div>
                        <div><input type="checkbox" name="flavor" value="시큼한 끝맛">시큼한 끝맛</div>
                        <div><input type="checkbox" name="flavor" value="약간의 쓴맛">약간의 쓴맛</div>
                        <div><input type="checkbox" name="flavor" value="신선한 홉 풍미">신선한 홉 풍미</div>
                        <div><input type="checkbox" name="flavor" value="쌀 풍미">쌀 풍미</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="약한 단맛">약한 단맛</div>
                        <div><input type="checkbox" name="flavor" value="로스팅과 구운 풍미">로스팅과 구운 풍미</div>
                        <div><input type="checkbox" name="flavor" value="청량함">청량함</div>
                        <div><input type="checkbox" name="flavor" value="신맛">신맛</div>
                        <div><input type="checkbox" name="flavor" value="가벼움">가벼움</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="스컹크 풍미">스컹크 풍미</div>
                        <div><input type="checkbox" name="flavor" value="홉의 풍미 많지 않음">홉의 풍미 많지 않음</div>
                        <div><input type="checkbox" name="flavor" value="깔끔함">깔끔함</div>
                        <div><input type="checkbox" name="flavor" value="허브 풍미">허브 풍미</div>
                        <div><input type="checkbox" name="flavor" value="약간의 쓴 맛">약간의 쓴 맛</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="flavor" value="약간의 단맛">약간의 단맛</div>
                        <div><input type="checkbox" name="flavor" value="매끄러운 맥아 풍미">매끄러운 맥아 풍미</div>
                        <div><input type="checkbox" name="flavor" value="약한 달콤한 맥아">약한 달콤한 맥아</div>
                        <div><input type="checkbox" name="flavor" value="빵 껍질">빵 껍질</div>
                        <div><input type="checkbox" name="flavor" value="">사과 주스 맛</div>
                    </div>
                </div>
            </div>

            <div class="beer_aroma">
                <div class="feature_title">5. 시즌 <span>다중 선택 가능</span></div>
                <div class="beer_checkbox">
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="season" value="연중 내내">연중 내내</div>
                        <div><input type="checkbox" name="season" value=""></div>
                        <div><input type="checkbox" name="season" value="여름">여름</div>
                        <div><input type="checkbox" name="season" value="9월">가을</div>
                        <div><input type="checkbox" name="season" value="10월">겨울</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="season" value="따듯한 날씨">따듯한 날씨</div>
                        <div><input type="checkbox" name="season" value="서늘한 계절">서늘한 계절</div>
                    </div>
                </div>
            </div>

            <div class="beer_aroma">
                <div class="feature_title">6. 어울리는 음식 <span>다중 선택 가능</span></div>
                <div class="beer_checkbox">
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="food" value="생선 요리">생선 요리</div>
                        <div><input type="checkbox" name="food" value="해산물">해산물</div>
                        <div><input type="checkbox" name="food" value="샐러드">샐러드</div>
                        <div><input type="checkbox" name="food" value="햄버거">햄버거</div>
                        <div><input type="checkbox" name="food" value="프렌치프라이">프렌치프라이</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="food" value="스테이크">스테이크</div>
                        <div><input type="checkbox" name="food" value="초콜릿">초콜릿</div>
                        <div><input type="checkbox" name="food" value="홍합">홍합</div>
                        <div><input type="checkbox" name="food" value=""></div>
                        <div><input type="checkbox" name="food" value="연어">연어</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="food" value="크림 리조또">크림 리조또</div>
                        <div><input type="checkbox" name="food" value="소시지">소시지</div>
                        <div><input type="checkbox" name="food" value="오리 구이">오리 구이</div>
                        <div><input type="checkbox" name="food" value="돼지고기 구이">돼지고기 구이</div>
                        <div><input type="checkbox" name="food" value="저크 치킨">저크 치킨</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="food" value="가벼운 음식">가벼운 음식</div>
                        <div><input type="checkbox" name="food" value="든든한 음식">든든한 음식</div>
                        <div><input type="checkbox" name="food" value="무거운 음식">무거운 음식</div>
                        <div><input type="checkbox" name="food" value="알싸한 쓴 음식">알싸한 쓴 음식</div>
                        <div><input type="checkbox" name="food" value="매운 음식">매운 음식</div>
                    </div>
                </div>
            </div>

            <div class="beer_aroma">
                <div class="feature_title">7. 목넘김 <span>다중 선택 가능</span></div>
                <div class="beer_checkbox">
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="body" value="드라이">드라이</div>
                        <div><input type="checkbox" name="body" value="깔끔함">깔끔함</div>
                        <div><input type="checkbox" name="body" value="가벼움">가벼움</div>
                        <div><input type="checkbox" name="body" value="부드러움">부드러움</div>
                        <div><input type="checkbox" name="body" value="걸쭉">걸쭉</div>
                    </div>
                    <div class="beer_checkbox_row">
                        <div><input type="checkbox" name="body" value="가벼운 탄산">가벼운 탄산</div>
                        <div><input type="checkbox" name="body" value="적당한 탄산">적당한 탄산</div>
                        <div><input type="checkbox" name="body" value="풍부한 탄산">풍부한 탄산</div>
                    </div>
                </div>
            </div>

            <div class="beer_submit">
                <button type="submit">제 출</button>
            </div>
        </form>
    </div>
    <div class="beer_btn_box">
        <button onclick="location.href='/history'">추천 히스토리 보러가기</button>
        <button onclick="location.href='/rating'">맥주 종류 보러가기</button>
    </div>
{% endblock content %}

3) templates/recommend/result.html

{% extends 'base.html' %}
{% load static %}

{% block link %}
    <link rel="stylesheet" href="{% static 'css/recommend.css' %}">
    <script defer src="{% static 'js/recommend.js' %}"></script>
{% endblock link %}

{% block title %}
    <title>My Little Beer</title>
{% endblock title %}

{% block content %}
    <div class="recommend_message_box">
        <div class="recommend_title">나에게 어울리는 맥주는??!!</div>
    </div>

    <div class="beer_result_box">
        <div class="beer_img_row">
            <div class="beer_img_box">
                <img src="{% get_static_prefix %}{{ beer.img_url }}"
                     alt=""/>
            </div>
            <div class="beer_img_box">
                <div>{{ beer.name }}</div>
                <span>맥주 평점 : {{ beer.rating }}</span>
                <br>
                <span>유사도 점수 : {{ score }} / 56</span>
            </div>
        </div>
        <div class="beer_info_row">
            <div class="beer_info_box">
                <div>1. 스타일 : <span>{{ beer.style }}</span></div>
                <div>2. 카테고리 : <span>{{ beer.category }}</span></div>
                <div>3. 향 : <span>{{ beer.aroma }}</span></div>
                <div>4. 맛 : <span>{{ beer.flavor }}</span></div>
                <div>5. 시즌 : <span>{{ beer.season }}</span></div>
                <div>6. 어울리는 안주 : <span>{{ beer.paring_food }}</span></div>
                <div>7. 목넘김 : <span>{{ beer.body }}</span></div>
            </div>
        </div>
    </div>
    <div class="beer_btn_box">
        <button onclick="location.href='/history'">추천 히스토리 보러가기</button>
        <button onclick="location.href='/rating'">맥주 종류 보러가기</button>
    </div>
{% endblock content %}

6. 기타 정보

1) 프로젝트 문서

https://www.notion.so/kimphysicsman/MLB-MyLittleBeer-3c4edfa70eb24593ab1cc9b05f8e6e61

2) github

https://github.com/nbcamp-AI-2-fantastic4/mylittlebeer

3) 추천시스템 코드

https://colab.research.google.com/drive/1eaEzktpnYVwAdhBeXs2LBt0xSENqSdtl

4) 발표영상

https://youtu.be/FcY93t-2oMI

profile
kimphysicsman

0개의 댓글