- ํ๋ก์ ํธ๋ช : moBee
- ํ์ : ์์คํ, ๋ฐฑํ๋
- ์
๋ฌด ๋ถ๋ด ๋ด์ญ
- ์์คํ : ๋ฐฑ์ค๋ + ํ๋ก ๋์๋ => ๊ธฐ๋ฅ ๋ด๋น
- ๋ฐฑํ๋: ํ๋ก ํธ์๋ + CSS/๋์์ธ => ๋์์ธ ๋ด๋น
์ํ ์ถ์ฒ, ์ํ ์์ธ ์กฐํ
๊ฟ๋ฒ์ด ์ถ์ฒํด์ฃผ๋ ๊ฟ์ผ ์ํ ์ถ์ฒ ์ฌ์ดํธ
- ํํ์ด์ง ์ค๋ช ๋ฐ ๊ฟ๋ฒ(ํ ๋ง) ์๊ฐ
-
๋ชจ๋ ์ํ ์กฐํ
- ์ต์ ์
- ์ถ์ฒ ์(์ฐํ ์)
-
์ถ์ฒ ์๊ณ ๋ฆฌ์ฆ์ ์ํ ์ถ์ฒ ์ํ
- ์ฌ์ฉ์๊ฐ ์ ํํ ๋ฆฌ๋ทฐ ์ ๋ณด์ ์ฐํ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ฌ์ฉ์ ์ ํธ๋ ์กฐ์ฌ
- ์ฐํ ์ํ์ ์ด๋ฏธ ๋ฆฌ๋ทฐ๋ฅผ ๋จ๊ธด ์ํ๋ ์ ์ธํ๊ณ ์ ํธ ์ฅ๋ฅด ๊ธฐ๋ฐ์ผ๋ก ์ฌ์ฉ์์๊ฒ ์ํ ์ถ์ฒ(์์ 10๊ฐ)
-
์ฅ๋ฅด๋ณ ์ํ ์ถ์ฒ
-
์ํ ์ ๋ชฉ์ ๊ฒ์์ผ๋ก ๊ตฌํ(๊ณต๋ฐฑ ์ ๊ฑฐํ์ฌ ๊ฒ์ํ๋๋ก ํ๋ค.)
- ๋ ธ๋ ํ ๋ง์ ์ด์ธ๋ฆฌ๋ ๋ฏธ๋์ธ์ฆ ์ด๋ฏธ์ง ์ฌ์ฉํ์ฌ ๊ตฌํ
- ์ํ ๊ด๋ จ ๊ฒ์๊ธ (CRUD, ์ข์์ ๊ธฐ๋ฅ)
- ์ต์ ์์ผ๋ก ์ ๋ ฌ
- ํ์ด์ง๋ค์ด์ ์ผ๋ก ์ฅ๊ณ ์์ 10๊ฐ์ฉ ๊ฒ์๋ฌผ์ ๊ฐ์ ธ์ค๊ฒ ๊ตฌํ
- ๋๊ธ CRUD
- ์ฐํ ์ํ ๋ชฉ๋ก
- ๋จ๊ธด ๋ฆฌ๋ทฐ (๋ณ์ ) ๋ชฉ๋ก
- ์ด ๊ฒ์๋ฌผ๊ณผ ๋จ๊ธด ๋๊ธ ๋ชฉ๋ก
- ์๊ณ ๋ฆฌ์ฆ์ ํตํ ์ ํธ ์ฅ๋ฅด ์ฐจํธ - ์ฅ๋ฅด๋ณ ์ ํธ๋๋ฅผ ํ๊ธฐ, ์ ํธ๋ best ์ฅ๋ฅด 5๊ฐ ์ถ๋ ฅ
- ๊ด๋ฆฌ์์ธ ๊ฒฝ์ฐ ์ํ ์์ฑ ๋ฒํผ
- TMDB๋ก๋ถํฐ ์ํ๋ฅผ ์๋์ผ๋ก ๋ฐ์์ค๋ ๋ฒํผ ๊ตฌํ(์ ๋ช ํ ์ํ, ์์ ์ค์ธ ์ํ)
- ์ด๊ธฐ์ ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ค ๋๋ ์ฉ์ด(์ฅ๋ฅด๋ ํจ๊ป ๋ฃ์ด์ค)
- ์ถ๊ฐ๋ก ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ฒํผ์ ๋๋ฌ ์์ฑํ ์ ์์
- ๋ฐ์์ค๊ณ ์ถ์ page ๊ฐ์๋ฅผ ์ ํ๋ค(page 1 ๋น ์ํ 20 ๊ฐ)
- TMDB ์ํ ์ ๋ณด ๋ฐ์์ค๊ธฐ(์ฅ๋ฅด, ์ค๊ฑฐ๋ฆฌ ๋ฑ ์ํ ๊ด๋ จ ์ ๋ณด)
- ํธ๋ ์ผ๋ฌ - ์ ํ๋ธ ์์
- ๋ฆฌ๋ทฐ CRUD + ๋ณ์ (์์ฑ ์์ ์๊ฐ ์ ๋ณด ํฌํจ) โ ๋๋ฅด๋ฉด ๋ชจ๋ฌ๋ก
- ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ง ์์ฑ(๋ณธ์ธ๋ง ์์ , ์ญ์ )
- ํ ๊ณ์ ๋น ํ๋์ ํ์ ๋ง
- ์ถ์ฐ ๋ฐฐ์ฐ, ๊ฐ๋ ์ ๋ณด => DB์์ ๊ฐ์ ธ์ค์ง ์๊ณ ์์ธ ์ ๋ณด ์ movie id๋ฅผ ํ์ฉํด TMDB์์ ๊ฐ์ ธ์จ๋ค.
- ๋ณด๊ณ ์ถ์ ์ํ ๋ฑ๋ก ๋ฒํผ(์ฐ)
ERD ์ ๋ณด - ERD Diagram
-
์ ์ฒด์ ์ธ ํ ๋ง: Bootswatch, ๋ถํธ์คํธ๋ฉ
-
์์ง์ด๋ ์ด๋ฏธ์ง: CodePen
-
์์ด์ฝ: fontawesome, flaticon
-
ํฐํธ: ๋๋, ๊ตฌ๊ธํฐํธ
-
์ฌ์ง: pixabay ๋ฑ
- migrate
- superuser ์์ฑ
- superuser๋ก ๋ก๊ทธ์ธํ์ฌ My Page์์ ์ํ ์์ฑ(๊ด๋ฆฌ์์ ์ด๊ธฐ ์ํ ๋ฐ์ดํฐ ์์ฑ ๋ฐ ์ถ๊ฐ ์์ฑ ๊ธฐ๋ฅ ๊ตฌํ)
- ์ํ ๊ฐ์ ธ์ค๋ ๊ฑด ๊ด๋ฆฌ์ ๊ณ์ ๋ง ๊ฐ๋ฅํ๋ค.(์ฅ๊ณ ์์๋ ๊ด๋ฆฌ์ ๊ณ์ ๋ง ๊ฐ์ ธ์ค๋๋ก ๊ตฌํ)
- TMDB์์ ๊ฐ์ ธ์ฌ Page(์ํ 20๊ฐ)๋ฅผ ์ ๋ ฅํ๊ณ ๋ฒํผ์ ๋๋ฌ ํ์ฌ ์์์ค์ธ ์ํ์ ์ ๋ช ํ ์ํ๋ค ์ค ๊ณจ๋ผ์ ๊ฐ์ ธ์จ๋ค.
- ์ด๋ฏธ์ง, ํธ๋ ์ผ๋ฌ์ ํ๋กํ, ๊ฐ๋ ์ด๋ฆ ์ ๋ณด๊ฐ ์๋ ๊ฒฝ์ฐ๋ ๊ฐ์ ธ์ค์ง ์๋๋ค. ๋ฐ๋ผ์ 100๊ฐ ๊ฐ์ ธ์ค๋ฉด 90๊ฐ ์ ๋ ์ ์ฅ๋๋ค!
- Intro Page
- Movie Home page
- ๋ก๊ทธ์ธ, ๋ก๊ทธ์์, ํ์๊ฐ์
- ์ํ ๊ฒ์ ๋ฐ
- UP ๋ฒํผ ํด๋ฆญ ์ ํ์ด์ง ์ต์๋จ์ผ๋ก ์ด๋ํ๋ ๋ฒํผ
- ์ฃผ์๋ก ๋ค์ด์ค๋ฉด ๊ฐ์ฅ ๋จผ์ ๋ณด์ด๋ ํ์ด์ง
- ์ฌ์ดํธ์ ๋ํ ์ค๋ช
- ์ํ ๋ฆฌ์คํธ ์กฐํ
- ์๋จ์ ํ์ฌ ์ํ 3๊ฐ์ ํฌ์คํฐ๋ฅผ ๋ง์ฐ์ค ๊ฐ๋ค๋๋ฉด ์์ง์ด๊ฒ ๊ตฌํ
- ์ฅ๋ฅด๋ณ, ์ต์ ์, ์ถ์ฒ ์(์ฐํ ์), ์ถ์ฒ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์ํ ์กฐํ (์ฒ์์ ์ต์ ์์ผ๋ก ๋ฌ๋ค.)
- ์๋จ nav bar์ ๊ฒ์์ผ๋ก๋ ํ์ฌ ์ํ ๋ฆฌ์คํธ ์ค ์กฐํ ๊ฐ๋ฅ!
- ์ํ๋ฅผ ์นด๋๋ก ๊ตฌํ(๋๋ ์ ๋ ๋ฐ์ํ๋๋ก ํ์ฉ)
- ์ํ๋ฅผ ์นด๋๋ฅผ ํ์ธํ๋ค๋ณด๋ฉด ์คํฌ๋กค์ด ๋ง์ด ๋ด๋ ค๊ฐ ์ ์์ผ๋, nav bar์ up๋ฒํผ์ ๊ตฌํํ์ฌ ๋๋ฅด๋ฉด ์ต์๋จ์ผ๋ก ์์ง์.
- ์ํ ์์ธ ์ ๋ณด(Poster img, BackDrop img, ์ ๋ชฉ, ๋ฐํ์, ์ฅ๋ฅด ๋ฑ)
- ์ํ ์ฐ๋ฒํผ ๊ตฌํ(๋นจ๊ฐ ํํธ) - ๋๋ฅด๋ฉด ์๊ฐ์ ์ผ๋ก ๋ฐ๋ก ์ ์ฉ
- ์ ์ ๋ค์ด ๊ณ ๋ฅธ ํ์ ์ ํ๊ท ๋ ์ก๊ฐํ ๋ชจ์์ ์์ด์ฝ์ผ๋ก ์๊ฐํ ํ์ฌ ๋ณด์ฌ์ค๋ค.
- 5๊ฐ๋ ๊ฟ์ผ 4๊ฐ๋ ์ฌ๋ฏธ 3๊ฐ๋ ํ๋ฒ 2๊ฐ๋ ์ง๋ฃจ 1๊ฐ๋ ๋ ธ์ผ
- ์ ํ๋ธ ํธ๋ ์ผ๋ฌ ์์(TMDB์์ ์์ key๋ฅผ ๋ฐ์์ URL์ ์ฐ๊ฒฐ, ์๋ ์ฌ์)
- ๋ฐฐ์ฐ์ ๊ฐ๋
์ TMDB API๋ก ์ฐ๊ฒฐํ์ฌ ๋ฐ์์จ๋ค.(DB์๋ ๋ฐ๋ก ์ ์ฅ X)
- ์์ธ์ ๋ณด ํ์ด์ง์์๋ง ๊ฒ์ํ๋ ๊ทธ๋๊ทธ๋ ๋ฐ์์ค๊ธฐ๋ก ํ๋ค.
- ์ํ์ ๋ฆฌ๋ทฐ CRUD ๊ตฌํ
- ์์ฑ, ์์ ์๊ฐ ํํ, ์์ฑ์ ํํ
- ์์ ์ด ์์ฑํ ๋ฆฌ๋ทฐ๋ ์์ ๋ง ์์
- ์ ๊ฑฐ๋ ๊ด๋ฆฌ์์ ์์ฑ์๋ง ๊ฐ๋ฅ
- ์์ฑ์ ๋ก๊ทธ์ธํ ์ ์ ๋ง ๊ฐ๋ฅ
- ์กฐํ๋ ๋ก๊ทธ์ธํ์ง ์์๋ ๊ฐ๋ฅ
- ์ํ์ ๋ํ ์ด์ผ๊ธฐ๋ฅผ ๋๋๋ ์ปค๋ฎค๋ํฐ
- ๊ฒ์๊ธ, ๋๊ธ CRUD
- ๋ก๊ทธ์ธํ์ง ์์๋ ์กฐํ ๊ฐ๋ฅ
- ๋ก๊ทธ์ธํด์ผ ์์ฑ ๊ฐ๋ฅ
- ์์ฑ์์ ๊ด๋ฆฌ์๋ง ์ญ์ ๊ฐ๋ฅ
- ์์ฑ์๋ง ์์ ๊ฐ๋ฅ
- ๊ฒ์๊ธ๊ณผ ๋๊ธ ๋ ๋ค ์์ฑ์๊ฐ ์์ ์๊ฐ ํฌํจ
- ๊ฒ์๊ธ ์ข์์ ๊ธฐ๋ฅ ๊ตฌํ
- ํ์ด์ง๋ค์ด์ ์ ๊ตฌํํ์ฌ ์ฅ๊ณ ์์ 10๊ฐ์ฉ ํ์ด์ง ๋ณ๋ก ๋ฐ์์จ๋ค.
- ๊ฒ์๊ธ ์กฐํ๋ ๋ชจ๋ฌ๋ก ๊ตฌํ
- ์ฐ๊ณผ ๋ฆฌ๋ทฐ๋ฅผ ํตํด ๋ถ์ํ ์ฅ๋ฅด ์ ํธ๋ ๊ทธ๋ํ๋ก ์๊ฐํ
- ์ข์ํ๋ ์ฅ๋ฅด top5
- ์ฐํ ์ํ(๋ด ๊ฟ๋จ์ง ์ํ)
- ๋จ๊ธด ๋ฆฌ๋ทฐ, ์์ฑํ ๊ฒ์๊ธ, ์์ฑํ ๋๊ธ ๋ชจ์
- ๊ด๋ฆฌ์์ธ ๊ฒฝ์ฐ๋ ์ํ ์์ฑ ํผ ์กด์ฌ
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly
# ๊ถํ ๋ถ์ฌ๋ api_view ์๋ ์ ์ด์ผ ํ๋ค!!
@api_view(['POST'])
@permission_classes([IsAdminUser]) # ๊ด๋ฆฌ์๋ง ๊ฐ๋ฅ!!
def movie_create(request, kind, pages):
pass- @permission_classes([IsAuthenticatedOrReadOnly]) : ๋ก๊ทธ์ธํ์ง ์์ ์ ์ ๋ ์ฝ๊ธฐ๋ง
- @permission_classes([IsAuthenticated]) : ๋ก๊ทธ์ธํ ์ ์ ๋ง
- @permission_classes([IsAdminUser]) : ๊ด๋ฆฌ์๋ง
- serializer๋ก ๋ฐ์ดํฐ๋ฅผ jsonํ ํ ํ data๋ฅผ ์ง์ add ํ๋ ๋ฐฉ๋ฒ
- SerializerMethodField ์ฌ์ฉ! ํจ์๋ฅผ ์ด์ฉํด ์ ์กํ ๋ฐ์ดํฐ์ ์ถ๊ฐ ํ๋๋ฅผ ์ง์ ํ ์ ์๋ค.
- ํจ์๋ฅผ ๋ง๋ค์ด return ๊ฐ์ ์ถ๊ฐ ํ๋ ๊ฐ์ผ๋ก ์ง์ ํ๋ค.
- ํจ์์ ์ธ์ ์ค self๋ ํ์ฌ serializer์ด๋ฉฐ, views.py์์ ์ ๋ ฅ์ผ๋ก ๋ฃ์ด์ฃผ๋ ๊ฐ์ ์ฌ์ฉํ ์ ์๋ค.
- ๊ฒ์๊ธ์์ ์์ฃผ ์ฌ์ฉํ๊ธฐ ์ข์ ํจ์
- ๋ช ๋ถ ์ , ๋ช ์๊ฐ ์ ๋ฑ์ผ๋ก ์ค์
- serializer์์ ์์ฑ
from django.utils import timezone
from datetime import datetime, timedelta
class ReviewSerializer(serializers.ModelSerializer):
created_at = serializers.SerializerMethodField('create_time')
updated_at = serializers.SerializerMethodField('update_time')
'''
...
'''
def create_time (self, my):
time = datetime.now(tz=timezone.utc) - my.created_at
if time < timedelta(minutes=1):
return '๋ฐฉ๊ธ ์ '
elif time < timedelta(hours=1):
return str(int(time.seconds / 60)) + '๋ถ ์ '
elif time < timedelta(days=1):
return str(int(time.seconds / 3600)) + '์๊ฐ ์ '
elif time < timedelta(days=7):
time = datetime.now(tz=timezone.utc).date() - my.created_at.date()
return str(time.days) + '์ผ ์ '
else:
return False
def update_time (self, my):
time = datetime.now(tz=timezone.utc) - my.updated_at
if time < timedelta(minutes=1):
return '๋ฐฉ๊ธ ์ '
elif time < timedelta(hours=1):
return str(int(time.seconds / 60)) + '๋ถ ์ '
elif time < timedelta(days=1):
return str(int(time.seconds / 3600)) + '์๊ฐ ์ '
elif time < timedelta(days=7):
time = datetime.now(tz=timezone.utc).date() - my.updated_at.date()
return str(time.days) + '์ผ ์ '
else:
return False
...-
includes๋ก ๊ตฌํ ์ํํ๋ฉฐ ์๋์ง ํ์ธํ๊ณ v-if๋ก ์๋ ๊ฒ๋ง ๋ ๋๋งํ๋ค.
-
ํ๊ธ์ v-model ๋์ ์ @input์ผ๋ก ํด๊ฒฐํ๋ค.
-
๋์ด์ฐ๊ธฐ ์๊ด ์์ด ๋จ๊ฒ
-
replace(/ /gi, '').includes(query)
-
input์๋ replace(/ /gi, '')๋ก query๋ฅผ ์ ๊ฑฐํด์ค๋ค.
-
- django
- view์์ ๋ณ๊ฒฝํด์ฃผ๋ฉด ๋๋ค.
from django.core.paginator import Paginator
...
paginator = Paginator(articles, 10)
page_num = request.GET.get('page')
page_obj = paginator.get_page(page_num)
serializer = ArticleListSerializer(page_obj, many=True)
data = {}
data['count'] = articles.count()
data['articles'] = serializer.data
return Response(data)-
vue
-
๊ฒฝ๋ก๋ฅผ articles: page => HOST + ARTICLES +
?page=${page}๋ก ?๋ก ํ์ด์ง๋ฅผ ์ ์ก -
ํ์ด์ง ๊ด๋ จ ์ ๋ณด๋ฅผ ๋ฐ์์ ๋๊ธด๋ค.
-
-
๋ชจ๋ธ์ด ๋ณต์กํด์ง๋, serializer๋ฅผ ์ ์ฐํ๊ฒ ๋ค๋ฃฐ ์ค ์์์ผ ํ๋ค.
- ์ฅ๊ณ serializer ๋ค๋ฃจ๋ ์ฌ๋ฌ ๋ฐฉ๋ฒ๋ค์ด ์กด์ฌ
-
์ฝ๋ํ์ ํ์ฉํ ๋ Vue์์ ์ฌ์ฉํ๊ธฐ ์ด๋ ค์ด ๋ฌธ๋ฒ๋ค์ด ๋ค์ ์กด์ฌ(์ฌ์ฉ์๋ค์ด ๋จ๊ธด ์ฝ๋๋ผ ๋ถ์ ํํ ์ ๋ณด๋ค๋ ํฌํจ)
- ์๊ฐ์ ๋ง์ด ์์๋ค. ํ๋ฃจ์ 13์๊ฐ ์ฉ ์ ๋ ๋ชป์๋ฉด์ ํ๋ค.๐ ๐
-
Vue Modal์์ ์ด๋ฒคํธ ์ ์ฉ ๊ด๋ จ ์ด๋ ค์์ ๊ฒช์.
-
Bootstrap Modal์ด ์๋ ๋ค๋ฅธ Modal ์ฌ์ฉ
-
์ฌ๋ฌ ์ปดํฌ๋ํธ๋ค์ด ๋ง์ ์ฐ๊ฒฐ ๊ด๊ณ๋ฅผ ์๊ฐํ๊ธฐ ๊น๋ค๋ก์ ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ฌ์ค๋ ์๊ฐ๋ ์์ด ๋ ๋๋งํ์ง ๋ชปํ๋ ์ค๋ฅ๋ ๋ฐ์ํ๋ค. ๋ผ์ดํ ์ฌ์ดํด ํ ์ด ์คํ๋ ๋ ์์๋ก ์๊ฐ์ด ํ๋ฅธ ๋ค ํจ์๋ฅผ ์คํํ๋๋ก ๋ณ๊ฒฝํ์ฌ ํด๊ฒฐํ์๋ค.
















