Vue with DRF
Server & Client
Server
โ ํด๋ผ์ด์ธํธ์ ์ ๋ณด์ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ ์ปดํจํฐ ์์คํ
โ ์๋น์ค ์ ์ฒด๋ฅผ ์ ๊ณต -> Django Web Service
โ ์ ๋ณด๋ฅผ ์ ๊ณต -> Django API Service
โ DB์ ํต์ ํ๋ฉฐ ๋ฐ์ดํฐ๋ฅผ ์์ฑ, ์กฐํ, ์์ , ์ญ์ ๋ฅผ ๋ด๋น
Client
โ Server๊ฐ ์ ๊ณตํ๋ ์๋น์ค์ ์ ์ ํ ์์ฒญ์ ํตํด Server๋ก๋ถํฐ ๋ฐํ ๋ฐ์ ์๋ต์ ์ฌ์ฉ์์๊ฒ ํํํ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง ํ๋ก๊ทธ๋จ ํน์ ์์คํ
โ ์๋ต๋ฐ์ ์ ๋ณด๋ฅผ ๊ฐ๊ณตํ์ฌ ํ๋ฉด์ ํํ
DRF
Back skeleton ์ฝ๋ ํ์ธ
- Models
from django.db import models
from django.conf import settings
# Create your models here.
class Article(models.Model):
# user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
- ์์ฒญ ๊ฒฝ๋ก ํ์ธ
# articles/urls.py
# from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from django.urls import path
from . import views
urlpatterns = [
path('articles/', views.article_list),
path('articles/<int:article_pk>/', views.article_detail),
path('comments/', views.comment_list),
path('comments/<int:comment_pk>/', views.comment_detail),
path('articles/<int:article_pk>/comments/', views.comment_create),
# # ํ์ ์์ฑ
# path('schema/', SpectacularAPIView.as_view(), name='schema'),
# # optional UI
# path('swagger/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
]
# my_api/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('articles.urls')),
# path('accounts/', include('dj_rest_auth.urls')),
# path('accounts/signup/', include('dj_rest_auth.registration.urls'))
]
- ๋๋ฏธ ๋ฐ์ดํฐ ์ฝ์
Vue
front ์ปดํฌ๋ํธ ๊ตฌ์กฐ ํ์ธ
๋ฉ์ธ ํ์ด์ง ๊ตฌ์ฑ
views/ArticleView.vue
component ํ์ธ ๋ฐ route ๋ฑ๋ก
// src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import ArticleView from '@/views/ArticleView'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'ArticleView',
component: ArticleView
},
...
]
// src/views/ArticleView.vue
<template>
<div>
<h1>Article Page</h1>
<hr />
</div>
</template>
<script>
export default {
name: "ArticleView",
components: {},
computed: {},
created() {},
methods: {},
};
</script>
src/App.vue
router-link ๋ฑ๋ก
// src/App.vue
<nav>
<router-link :to="{ name: 'ArticleView' }">Articles</router-link>
</nav>
components/ArticleList.vue
ํ์ธ
// components/ArticleList.vue
<template>
<div class="article-list">
<h3>Article List</h3>
</div>
</template>
<script>
export default {
name: 'ArticleList',
components: {
},
computed: {
}
}
</script>
<style>
.article-list {
text-align: start;
}
</style>
- ArticleList ํ์ ์ปดํฌ๋ํธ ๋ฑ๋ก
// views/ArticleView.vue
<template>
<div>
<h1>Article Page</h1>
<hr>
<ArticleList/>
</div>
</template>
<script>
import ArticleList from '@/components/ArticleList'
export default {
name: 'ArticleView',
components: {
ArticleList
},
computed:{
},
created() {
},
methods: {
}
}
</script>
components/ArticleListItem.vue
ํ์ธ
// compoents/ArticleListItem.vue
<template>
<div>
<h5>PK</h5>
<p>์ ๋ชฉ</p>
<hr>
</div>
</template>
<script>
export default {
name: 'ArticleListItem',
}
</script>
- ArticleListItem ํ์ ์ปดํฌ๋ํธ ๋ฑ๋ก
// components/ArticleList.vue
<template>
<div class="article-list">
<h3>Article List</h3>
<ArticleListItem/>
</div>
</template>
<script>
import ArticleListItem from '@/components/ArticleListItem'
export default {
name: 'ArticleList',
components: {
ArticleListItem
},
computed: {
}
}
</script>
store/index.js
state์ article ๋ฐฐ์ด ์ ์
// store/index.js
export default new Vuex.Store({
state: {
articles: [
{
id: 1,
title: '์ ๋ชฉ',
content: '๋ด์ฉ'
},
{
id: 2,
title: '์ ๋ชฉ2',
content: '๋ด์ฉ2'
},
],
},
})
- state์์ articles ๋ฐ์ดํฐ ๊ฐ์ ธ์์ pass props
// components/ArticleList.vue
<template>
<div class="article-list">
<h3>Article List</h3>
<ArticleListItem
v-for="article in articles"
:key="article.id"
:article='article'
/>
</div>
</template>
<script>
import ArticleListItem from '@/components/ArticleListItem'
export default {
name: 'ArticleList',
components: {
ArticleListItem
},
computed: {
articles() {
return this.$store.state.articles
}
}
}
</script>
- ๋ด๋ ค ๋ฐ์ prop ๋ฐ์ดํฐ๋ก ํ๋ฉด ๊ตฌ์ฑ
// compoents/ArticleListItem.vue
<template>
<div>
<h5>{{ article.id }}</h5>
<p>{{ article.title }}</p>
<hr>
</div>
</template>
<script>
export default {
name: 'ArticleListItem',
props: {
article: Object
}
}
</script>
Vue with DRF
AJAX ์์ฒญ ์ค๋น
- axios ์ค์
$ npm install axios
// store/index.js
import axios from 'axios'
const API_URL = 'http://127.0.0.1:8000'
โ ์์ฒญ ๋ณด๋ผ API server ๋๋ฉ์ธ ๋ณ์์ ๋ด๊ธฐ
getArticles
๋ฉ์๋ ์ ์
// store/index.js
export default new Vuex.Store({
...
actions: {
getArticles(context) {
axios({
method: 'get',
url: `${API_URL}/api/v1/articles/`
})
.then((res) => {
console.log(res, context)
})
.catch((err) => {
console.log(err)
})
}
},
})
- view์์
getArticles
actions ํธ์ถ
// vies/ArticleView.vue
<script>
import ArticleList from '@/components/ArticleList'
export default {
name: 'ArticleView',
components: {
ArticleList
},
computed:{
},
created() {
this.getArticles()
},
methods: {
getArticles() {
this.$store.dispatch('getArticles')
}
}
}
</script>
โ ์ธ์คํด์ค๊ฐ ์์ฑ๋ ์งํ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ํด created() hook ์ฌ์ฉ
์์ฒญ ๊ฒฐ๊ณผ ํ์ธ
โ server์์๋ 200์ ๋ฐํํ์์ผ๋ client console์์๋ Error ๋ฐ์!
'โญ Personal_Study > Vue' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Vue with DRF (0) | 2022.11.21 |
---|---|
Cross - Origin Resource Sharing (CORS) (0) | 2022.11.20 |
Article with Vue (0) | 2022.11.19 |
Navigation Guard (0) | 2022.11.19 |
Vue Router (0) | 2022.11.18 |
๋๊ธ