TMDB API์ YOUTUBE API๋ฅผ ํ์ฉํ ์ ๋ฐํ ์ํ ์ ๋ณด ์ ๊ณต ๋ฐ ์ปค๋ฎค๋ํฐ ์ฌ์ดํธ์ ๋๋ค.
- Django์ Vue.js๋ก ํ์คํ ๊ฐ๋ฐ์ ํ ์ ์๋ค.
- ์ธ๋ถ API๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
CORS
์simple jwt
๋ก ์๋ฒ-ํด๋ผ์ด์ธํธ ํต์ ๊ณผ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ค.- SPA์ ํ๊ณ์ ์ ๋ณด์ํ๊ณ ์,
vue-router
๋ฅผ ์ด์ฉํ์ฌ ์ฌ์ฉ์๋ก ํ์ฌ๊ธ url์ด ์ด๋๋ ๊ฒ ์ฒ๋ผ ๋ณด์ด๊ฒ ํ๋ฉฐ, ๋ค๋ก ๊ฐ๊ธฐ๋ฅผ ์ง์ํ๋ค. - RESTfulํ url์ ๊ตฌ์ฑํ ์ ์๊ณ , ๋ค์ํ method๋ก
axios
์์ฒญ์ ๋ณด๋ผ ์ ์๋ค.
Django | Vue.js |
---|---|
django rest framework image-kit simple jwt django cors headers requests |
vuex vue-router axios vue-bootstrap vue-fontawesome |
Back๊ณผ front๋ฅผ ๋ถ๋ฆฌํ์ง ์์๊ณ , ์ด๋ฐ ์ค๊ณ๋ฅผ ๊ฐ์ด ์งํํ๋ค.
๋ฐ์ง์ | ์ ๋์ค |
---|---|
์ํ ๋ฉ์ธ, ๋ํ
์ผ ํ๋ก ํธ ๋์์ธ ์ํ ์ถ์ฒ ์ํ ๊ฒ์ |
์ํ ์ปค๋ฎค๋ํฐ ๋์์ธ backend์์ model ์์ Modal |
์ถ๊ฐ๋ก ์๋์ ๊ฐ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ คํ์ผ๋,
- ์์ ๋ณ์
- ๋ด ํด๋ ๊ธฐ๋ฅ
- ์ฑ๋ณ ๋ฐ ์ฐ๋ น๋๋ณ ๋ณ์ ํํฐ๋ง
์งง์ ํ๋ก์ ํธ ๊ธฐ๊ฐ์ผ๋ก ์ธํด, ์ฃผ์๊ธฐ๋ฅ์ ์ถฉ์คํ๊ณ ์ ํ๋ค.
User์ movie ๋ ๊ฐ์ ๋ชจ๋ธ์ ์ค์ฌ์ผ๋ก Comment, RatedMovie, LikedMovie ๋ฑ์ 1:N ๋๋ M:N์ผ๋ก ๋ชจ๋ธ๋งํ๋ค.
- ๊ฒ์๊ธฐ๋ฅ
- ๊ฐ์ฅ ์ธ๊ธฐ ๋ง์ ์ํ์ ํธ๋ ์ผ๋ฌ
- ์ธ๊ธฐ์ํ, ํ์ฌ ์์์, ์ด๋ฒ ์ฃผ ์ธ๊ธฐ์ ์ ๋ณด ์ ๊ณต
- ํ๋ฉด์ ์กด์ฌํ๋ ํฌ์คํฐ๋ฅผ ํด๋ฆญํ๋ฉด ๋ชจ๋ ๋ํ ์ผ ํ์ด์ง๋ก ์ด๋
-
Navbar ์๋์ tmdb์ backdrop_path๋ฅผ ํตํ ๊ทธ๋ผ๋ฐ์ด์ ๋ฐฑ๊ทธ๋ผ์ด๋
-
๋ง์ฐ์ค hover์ ๋ฐ์ํ์ผ๋ก ์ ์.
-
Hooper swiper๋ฅผ ์ด์ฉํด ๋ง์ฐ์ค ํด๋ฆญ ๋๋ ๋๋๊ทธ๋ก ๋ค์ํ ์ํ ์ ๋ณด๋ฅผ ํ๋ฒ์ ์ ๊ณต.
-
starating๋ฅผ ํตํด ํด๋ฆญ ๋๋ ๋๋๊ทธ๋ก ๋ณ์ ๋งค๊ธฐ๊ธฐ.
-
ํ์ฌ ์ฐ๋ฆฌ ์ฌ์ดํธ์ ๊ฐ์ ํ ์ ์ ๊ฐ ๋งค๊ธด ํ์ ์ ํ๊ท ๋ฐ ์ ์ ๊ฐ ๋๋ฅธ ์ข์์ ์ ์ ๊ณต
-
TMDB ์ฌ์ดํธ์ ์ ๋ณด ์ ๊ณต (๋ฐฐ์ฐ ์ ๋ณด, TMDB ํ์ ๋ฐ ํฌํ์, overview ๋ฑ)
-
ํ๋จ์ ํ์ฌ ๋ํ ์ผ ํ์ด์ง ์์ ์ํ์ ๊ด๋ จ๋ ์ ์ฌ ์ํ ์ ๊ณต
-
comment
ํด๋ฆญ ์, ๋๊ธ ํ์ด์ง๋ก ์ด๋ ๊ฐ๋ฅ
- starating์ ์ฌ์ฉํ์ฌ, ๋ณ์ ์ฃผ๊ธฐ ํธ์์ฑ์ ๋์.
- ๊ทธ๋ผ๋ฐ์ด์ ๋ฐฑ๊ทธ๋ผ์ด๋
- bootstrap icon์ ํตํด ์์๋ณด๊ธฐ ์ฌ์ด ์์ด์ฝ ์ฝ์ .
๋ํ
์ผ ํ์ด์ง์์ comment
ํด๋ฆญ ์, ๋ฒ ์คํธ ๋๊ธ ๋ชจ์ modal
๋ฑ์ฅ
- ๋ํ ์ผ ํ์ด์ง์ ์ํ ๋๊ธ ์ค, ๊ฐ์ฅ ์ข์์๊ฐ ๋ง์ ์์๋ก ๋ณด์ฌ์ค.
- ๊ธด ๋๊ธ์ ๊ฒฝ์ฐ์ ์ ๋ถ ๋ณด์ฌ์ฃผ์ง ์์.
more comments
๋ฒํผ์ ํตํด ๋๊ธ ์์ธ ํ์ด์ง๋ก ์ด๋ ๊ฐ๋ฅ- ์ข์์ ๋๋ฅด๊ธฐ ๊ฐ๋ฅ
- vue-js-modal์ ํตํด ์ฝ๊ฒ ๋๊ธ ํ์ ๊ฐ๋ฅ
- ์์ฑ์ ์์ ํ๋กํ ์ฌ์ง ์ฝ์
- boostrap icon ์ฌ์ฉ
-
๋๊ธ ์์ฑ ๋ฒํผ ํด๋ฆญ ์, ๋๊ธ ์์ฑ modal์ด ๋ฐ์ํ๊ณ ์์ฑ๊ฐ๋ฅ.
-
๊ฐ ๋๊ธ์ ๋ํ ๋๋๊ธ ์์ฑ ๊ฐ๋ฅ
-
์์ ์ด ๋จ ๋๊ธ์ ํํด ์ญ์ ๋ฐ ์์ ๊ฐ๋ฅ
-
๊ฐ ์ ์ ๊ฐ ๋งค๊ธด ๋ณ์ ์ด ์กด์ฌํ ์, ์ข์ธก ์๋จ์ ๋๊ธ ์ด ์ ์ ์ ๋ณ์ ์ ๊ณต.
์๋จ navbar์์ Recommendation
ํด๋ฆญ ์, ์ถ์ฒ ํ์ด์ง๋ก ์ด๋
- ๋ด๊ฐ ์ต๊ทผ์ ์ข์์๋ฅผ ๋๋ฅธ ์์๋ก ์ ํํ ์ ์๋ ํ๋ฉด ์ ๊ณต.
- ๋ง์์ ๋๋ ์ํ ํด๋ฆญ ์, TMDB์ recommendation์ ํตํด ์ํ ์ถ์ฒ.
- ์ํ ํด๋ฆญ ์, ๋ํ ์ผ ํ์ด์ง๋ก ์ด๋.
- ์ํ ํฌ์คํฐ hover ์, ํ์ ๊ธฐ๋ฅ.
- ์๋จ navbar์ search ์ฐฝ์ ๊ฒ์ ํ, enter ๋๋ ๋๋ณด๊ธฐ ๋ฒํผ ํด๋ฆญ ์ ๊ฒ์ ๊ฐ๋ฅ
- ๋งจ์์ ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณต
- ํ๋จ similar movie์์๋ ๊ฒ์ ๊ฒฐ๊ณผ์ ๊ด๋ จ๋ ์ํ๋ฅผ ์ ๊ณต
- ํฌ์คํฐ ํด๋ฆญ ์, ๋ํ ์ผ๋ก ์ด๋.
- ์๋จ ์ฐ์ธก, profile ๋ฒํผ ํด๋ฆญ ์ ์ด๋๊ฐ๋ฅ
- ๋ด ํ๋กํ์์๋ ์ค์ ๋ฒํผ์, ๋ค๋ฅธ ์ฌ๋์ ํ๋กํ์์๋ ํ๋ก์ฐ ๋ฒํผ์ ์ ๊ณต
- ์๋์ ๋ด๊ฐ ์ข์์์ ํ๊ฐํ ์ํ ์ ๋ณด๋ฅผ ์ ๊ณต ํด๋ฆญ์ ๋ํ ์ผ ์ด๋.
- ์ค์ ํด๋ฆญ ์, ์ ๋ณด ์์ ๋๋ ํํด ์ ํ.
- ํํด ํด๋ฆญ ์, ๊ท์ฌ์ด ๊ฒฝ๊ณ ๋ฌธ๊ตฌ์ ํจ๊ป ํํด์ฌ๋ถ ์ ํ
- ํ์์ ๋ณด ์กฐํ ๋ฐ ์์ ๊ฐ๋ฅ
- ์์ ๋ฒํผ ํด๋ฆญ ์ ์์ ๋ชจ๋ ์ง์
- ์ด๋ฏธ์ง ํ๋กํ๋ ์์ ๊ฐ๋ฅํ๋ฉฐ, ์ ๋ก๋๋ฅผ ํ์ง ์์ ์ ๊ธฐ๋ณธ ์ด๋ฏธ์ง ์ ๊ณต.
- ๋ํ
์ฌ๊ธฐ
ํด๋ฆญ ์ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ๊ฐ๋ฅํ๋ฉฐ, ์ ๋ณด ์ค๋ฅ ์ ๊ฒฝ๊ณ ๋ฌธ๊ตฌ.
- ๊ด๋ฆฌ์ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธ ์ ์ฐ์ธก ์๋จ์ admin ํ๊ทธ ๋ ธ์ถ.
- ํด๋ฆญ ์ admin ํ์ด์ง๋ก ์ด๋.
vuex
- vuex ์ฌ์ฉ ์ ๋น๋๊ธฐ์ ์ฒ๋ฆฌ์์ ์ด๋ ค์ ์ผ๋ฉฐ, ์ง์ญ์ ์ผ๋ก ์ฌ์ฉํ ๊ฒฝ์ฐ์๋ component ๋ด์์ method์ state๋ฅผ ์ ์ํ๋ ๊ฒ ํจ์ฌ ์ข์๋ค.
- state๋ฅผ ๋ค์ computed์ ๋ฃ์ด์ ๊ด๋ฆฌํ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ์ ๋์์๊ธฐ๊ฐ ๋ฌ๋ผ ์์์น ๋ชปํ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
v-if
๋ฑ์ผ๋ก ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ ๋์๋ง ๋์ํ๋๋ก ํ์ฌ ์๋ฌ๋ฅผ ํด๊ฒฐํ๋ค.- vuex์์๋ ํ๋ก์ ํธ์ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด์ ๋ชจ๋๋ก ๋๋์ด ๊ด๋ฆฌ์ฉ์ด์ฑ์ ์ฆ๊ฐ์์ผฐ๋ค.
axios
- axios์ default ๊ฐ(intercept, baseurl)์ ๋ณ๊ฒฝํ์ ๋, ๋ชจ๋ axios์์ ์ ์ฉ์ด ๋์ด์ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ง ๋ชปํ๋ค.
- ๊ทธ๋์ ์ดํ, axios ์์ฒญ๋ง๋ค ๋ฐ๋ก header ๋๋ URL๋ฅผ ์ง์ ํ์ฌ ํด๊ฒฐํ์๋ค.
- get์ ๊ฒฝ์ฐ 2๋ฒ์งธ ์ธ์๋ก header๋ฅผ ๋ฐ๊ณ , post, put ๋ฑ์ 3๋ฒ์งธ ์ธ์๋ก header๋ฅผ ๋ฐ์๋๋ฐ ์ ๋ถ ๋๋ฒ์งธ์ ๋ฃ์ด์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
- ์ฆ ํค๋๊ฐ ์๋ payload๋ก ๋ณด๋๊ณ , ์ดํ Network ํญ์์ ์ค๋ฅ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ์์ ํ์๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด์ฉํ ๋ README๊ฐ ๋ถ์คํ์ฌ ์ฒ์์ ์ฌ๋๋ก ์ฌ์ฉํ๊ธฐ ์ด๋ ค์ ๋ค.
- ๋ค์ํ ์์ ๋ฅผ ๊ฒ์ํ๊ณ , ์ง์ node module ์์ ์๋ ์ฝ๋๋ ์์ ํ๋ฉฐ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๊ณ ์ ํ๋ ๋ฐฉํฅ์ผ๋ก ์ด๋์๋ค.
- vue-js-modal์ ์ฌ๋งํ๋ฉด ์ฌ์ฉํ์ง ๋ง์!
transition
- ๋ทํ๋ฆญ์ค์ ๋ชจ๋ฌ๊ณผ ๊ฐ์ ํจ๊ณผ๋ฅผ ์ฃผ๊ธฐ ์ํด์, transition์ด๋ผ๊ณ ํ๋ css ๊ตฌ๋ฌธ ์ฌ์ฉํ๋ค.
- ์์ฐ์ค๋ฝ๊ฒ ์์๊ฐ ์ ํ๋์๋ค๋ ๊ฒ์ ๋ณด์ฌ์ค ์ ์๋ค.
UX
- ์ ์ ์๊ฒ ์ ํ๊ฐ๋ฅํจ์ ์๋ ค์ฃผ๊ธฐ ์ํด, ์ ํ ๊ฐ๋ฅํ ์์์ ๋ํด cursor๋ฅผ pointer๋ก ๋ณ๊ฒฝํด์ฃผ์๋ค.
- ๋ฐ์ดํฐ๋ฅผ ์๋ฒ๋ API๋ก๋ถํฐ ๊ฐ์ ธ์ค๋๋ฐ ์๊ฐ์ด ์์๋๊ธฐ ๋๋ฌธ์ ๋ก๋ฉ ํ์ด์ง๋ฅผ ๋ฃ์ด ์ฌ์ฉ์๊ฐ ๊ทธ ์๊ฐ์ ์ธ์ํ ์ ์๊ฒ๋ ํด์ฃผ์๋ค.
- modal๋ฅผ ํตํด ์ด๋ํ์ง ์๊ณ ๋ ์์ ๊ณผ ์์ฑ์ด ๊ฐ๋ฅํ๊ฒ ํ์๋ค.
- starating์ผ๋ก ์์ฝ๊ฒ ๋ณ์ ์ ์ค ์ ์๋๋ก ํ์๋ค.
- router ์ฌ์ฉํด์ URL๋ง ๋ณ๊ฒฝํจ์ผ๋ก์จ ์ฌ์ฉ์์๊ฒ ํ์ด์ง๋ฅผ ์ด๋ํ์์ ์ธ์์ํค๊ณ ํ์คํ ๋ฆฌ ๋ชจ๋๋ฅผ ํตํด ๋ค๋ก๊ฐ๊ธฐ๊ฐ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
router
- router ์ ์ญ ๊ฐ๋๋ฅผ ํตํด ๋ก๊ทธ์ธ ์์๋ง ์๋น์ค์ ์ ๊ทผํ ์ ์๋๋ก ์ ํํ์๋ค.
- ๋น๋ก๊ทธ์ธ ์์๋ ํ์๊ฐ์ ๊ณผ ๋ก๊ทธ์ธ ํ์ด์ง๋ง ๊ฐ ์ ์๋๋ก ํ์๋ค.
- ๋์ ๋ผ์ฐํ (query, params)์ ์ด์ฉํด URL ์์ฒด์ ์ ๋ณด๋ฅผ ์ค์๋ค.
localstorage
- ๋ก์ปฌ ์คํ ๋ฆฌ์ง์๋ ๋ชจ๋ ๊ฒ์ด ๋ฌธ์์ด๋ก ์ ์ฅ๋๋ค.
- ๋ง์ฝ ์๋ก๊ณ ์นจ์ ํ๋๋ผ๋ ์ ๋ณด๊ฐ ํ์ํ ์, ๋ฏผ๊ฐํ ์ ๋ณด๊ฐ ์๋๋ผ๋ฉด ๋ก์ปฌ์ ์ ์ฅํ์.
ํ์ผ ๊ด๋ฆฌ
- ์ ์ด์ component๋ฅผ ์์ฑํ ๋, ํ์ผ ๊ตฌ์กฐ๋ฅผ ์ก์์ ์์ฑํ๋๋ก ํ์.
- ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด ๊ด๋ฆฌ๊ฐ ํ๋ค๋ค.
Component
- ๋ง์ฝ ๋ํ
์ผ ํ์ด์ง์์ ๋ํ
์ผ ํ์ด์ง๋ก ๋์ด๊ฐ ๊ฒฝ์ฐ์๋
created
์ ๊ฐ์ life cycle hook์ด ์๋ํ์ง ์๋๋ค. - ์ด๋ด ๋์๋, ๋์ ๋ผ์ฐํ
์ ์ด์ฉํ์ฌ watch๋ก
$route
๋ฅผ ๊ฐ์ํ์ฌ ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฉํ๋ค. - style์ ๊ฒฝ์ฐ์๋ computed๋ฅผ ํ์ฉํ ์ ์๋ค.
- ๋ชจ๋ธ ์ค๊ณ๋ฅผ ์ํ์!!! ๋์ค์ ์์ ํ๋ ค๋ฉด front-end๋ ๋ชจ๋ ์์ ํด์ผํ ์๋ ์๋ค.
Model
from django.db import models
from django.conf import settings
from django.db.models.fields import CharField
User = settings.AUTH_USER_MODEL
class Movie(models.Model):
tmdb_id = models.CharField(max_length=50, unique=True)
title = models.CharField(max_length=100, null=True)
poster_path = models.CharField(max_length=200, null=True)
backdrop_path = models.CharField(max_length=200, null=True)
like_users = models.ManyToManyField(User, related_name='like_movies')
class Comment(models.Model):
like_users = models.ManyToManyField(User, related_name='like_comments')
user = models.ForeignKey(User, on_delete=models.CASCADE)
movie = models.ForeignKey(Movie, on_delete=models.CASCADE, related_name='comments')
content = models.CharField(max_length=1000)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class ReComment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
comment = models.ForeignKey(Comment, on_delete=models.CASCADE, related_name='recomments')
content = models.CharField(max_length=1000)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class RatedMovie(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='rated_movies')
movie = models.ForeignKey(Movie, on_delete=models.CASCADE, related_name='rates')
rate = models.IntegerField()
URL
# movie_api/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from rest_framework_simplejwt.views import (
TokenObtainPairView,
# TokenRefreshView,
)
urlpatterns = [
path('admin/', admin.site.urls), # GET admin ํ์ด์ง
path('api/v1/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), # POST ๋ก๊ทธ์ธ ์ ํ ํฐ ๋ฐํ.
path('api/v1/accounts/', include('accounts.urls')), # accounts
path('api/v1/movies/', include('movies.urls')), # movies
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # media ํ์ผ ์ ์ฅ์ ์ํ URL ๋ฐ root
# movies/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('<int:tmdb_id>/comment/', views.comment_list_create), # GET POST comment ๊ด๋ จ ์ ๋ณด ์ ์ฅ ๋ฐ ์กฐํ
path('<int:tmdb_id>/comment/<int:comment_id>/', views.comment_update_delete), # PUT DELETE ๋๊ธ ์์ ๋ฐ ์ญ์ .
path('<int:tmdb_id>/like/', views.movie_like,), # POST ์ํ ์ข์์ ์์ ๋ฐ ์์ฑ
path('comments/<int:comment_id>/like/', views.comment_like,), # GET POST ๋๊ธ ์ข์์ ๋ฐ ์ข์์ ์กฐํ
path('<int:tmdb_id>/rate/', views.movie_rate), # GET POST ์ํ ํ์ ์์ ๋ฐ ์์ฑ
path('<int:comment_id>/recomment/', views.recomment_list_create), # GET POST ๋๋๊ธ ์์ฑ ๋ฐ ์กฐํ
path('<int:comment_id>/recomment/<int:recomment_id>/', views.recomment_delete), # DELETE ๋๋๊ธ ์ญ์
path('<int:tmdb_id>/like/rate/', views.get_like_rate), # GET ์ํ ์ข์์ ๋ฐ ๋ณ์ ์กฐํ
path('<int:tmdb_id>/comments/best/', views.get_best_comment), # GET ๋ฒ ์คํธ ๋๊ธ ์กฐํ
path('<int:tmdb_id>/', views.set_initial_movie_info), # POST ์ํ ๋ํ
์ผ ํ์ด์ง ์ต์ด ์ง์
์์๋ง ์ ์ฅ
path('<int:tmdb_id>/backdrop/', views.get_backdrop), # GET ์ํ ๋ท๋ฐฐ๊ฒฝ ๊ฐ์ ธ์ค๊ธฐ.
]
# accounts/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.signup), # POST ํ์๊ฐ์
path('users/', views.user_update_delete), # GET PUT DELETE ์ ์ ํ์์ ๋ณด ์์ ๋ฐ ์ญ์ ๊ทธ๋ฆฌ๊ณ ์กฐํ
path('password-change/', views.user_password_change), # PUT ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ
path('<username>/follow/', views.follow), # GET POST ์ ์ ํ๋ก์ฐ ์ ๋ณด ์กฐํ ๋ฐ ์์
path('issuperuser/', views.is_superuser), # GET ์ํผ ์ ์ ์ธ์ง ํ๋ณ.
path('<username>/user/movies/', views.user_movie_info), # GET ์ ์ ์ rated movie & liked movie ์ ๋ณด ์กฐํ
]
serializers
- ์ด๋ฒ ํ๋ก์ ํธ์์ ๊ฐ์ฅ ๋ง์ด ์ด serializer method
get_<field_name>
์ผ๋ก ์์ฑ ์, ์๋ก์ด ํ๋๋ฅผ serializer ์ถ๊ฐ ๊ฐ๋ฅ
class CommentListSerializer(serializers.ModelSerializer):
username = serializers.SerializerMethodField()
# ์ด๊ฑด read_only
# get_<field_name>์ผ๋ก ๋ฉ์๋ ์์ฑ
# self => instance, obj => Model
def get_username(self, obj):
return obj.user.username
...
fields=(...'username',) # ์ด๋ ๊ฒ ์ถ๊ฐ.
์ง์
- ๋์ค๋๊ณผ ํจ๊ป ํ๋ฉด์ ์ฆ๊ฑฐ์ ๋ค.
- ์๋๋ ๋ฐฑ์๋๋ง ์๊ฐํ์๋๋ฐ, ํ๋ก ํธ๋ ํ๋ค๋ณด๋ ํฅ๋ฏธ๊ฐ ์๊ฒจ์ ์ด ๋ถ์ผ๋ ๊ณ ๋ คํด๋ด์ผ๊ฒ ๋ค.
๋์ค
- ์ง์๋๊ณผ ํจ๊ป ํ๋ฉด์, css์ ๋์์ธ์ ๋ํด ๋ง์ด ๋ฐฐ์ธ ์ ์์๋ค.
- ํ๋ก์ ํธ ๊ธฐ๊ฐ์ด ์ ๋ง ์งง๊ณ ํ๋ค์์ง๋ง, ๊ฐ์ด ํ๋ค๋ณด๋ ์ฌ๋ฐ๊ฒ ์ ๋๋ผ ์ ์์๋ค.
- ์์ผ๋ก์ ์ธ๋ฒ์ ํ๋ก์ ํธ๋ ์ ๋๋ด๊ณ ์ถ๋ค.