
์ด๋ฒ ํธ๋ ๊ผญ ์ง์ ์ฌ๋ฌ ๋ฒ ๋ฐ๋ณตํด๋ณด์ธ์.ํนํ ์๋ ํ๋ฆ์ ๋ฐ๋์ ์์ ์ตํ์ผ ํฉ๋๋ค.
GET
โ ํผ ๋ณด์ฌ์ฃผ๊ธฐ
POST
โ ๊ฒ์ฆ
โ ์ ์ฅ
โ redirect
์ด ํจํด์ด Django Form ์ฒ๋ฆฌ์ ํต์ฌ์
๋๋ค.
ํต์ฌ๋ง ๊ธฐ์ตํ๋ฉด ๋ฉ๋๋ค:
GET = ๋ณด์ฌ์ฃผ๊ธฐ / POST = ์ฒ๋ฆฌํ๊ธฐ / redirect = ๋ค์ ์ฅ์๋ก ๋ณด๋ด๊ธฐ
์ด ์ธ ๊ฐ์ง๊ฐ ์น์ ๋ชจ๋ ๋์์ ๊ธฐ๋ณธ์ ๋๋ค. ๋ ๊ถ๊ธํ ๋ถ๋ถ ์์ผ๋ฉด ๋ง์ํด ์ฃผ์ธ์!
https://velog.io/@hy_1023/GET-vs-POST-%EC%B0%A8%EC%9D%B4

๊ทธ์ ์1ํธ์์ 0๋ฒ~3๋ฒ
2~. 4๋ฒ~5๋ฒ
3~6. 6๋ฒ~10๋ฒ
7~10. 11๋ฒ~14๋ฒ
11~14. 15๋ฒ~17๋ฒ
15~18. 18๋ฒ~22๋ฒ
19~20. 23๋ฒ~25๋ฒ
21~. 27๋ฒ
22~. 28๋ฒ
๊ทธ์ธ~ 29๋ฒ~31๋ฒ
# models.py์ ํ๋๋ฅผ ์๋์ผ๋ก HTML ํผ์ผ๋ก ๋ณํ
class PostForm(ModelForm):
class Meta:
model = Post
fields = ['title', 'content']
DB ๋ชจ๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ์ ๋ ฅ ํผ์ ์๋ ์์ฑํด์ฃผ๋ ์ญํ
์ง๋ฌธ
models.py์ ํ๋๋ฅผ ์๋์ผ๋ก HTML ํผ์ผ๋ก ๋ณํ class PostForm(ModelForm): class Meta: model = Post fields = ['title', 'content'] > DB ๋ชจ๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ์ ๋ ฅ ํผ์ ์๋ ์์ฑํด์ฃผ๋ ์ญํ ๋ชจ๋ธํผ์ ์ฅ๊ณ ๋ด์ฅ ํจ์์ธ๊ฑด๊ฐ?
๋ต๋ณ
Django ๋ด์ฅ ํด๋์ค์ ๋๋ค
์ด๋์ ๊ฐ์ ธ์ค๋์?
# Django ๋ด์ฅ ๋ชจ๋์์ import
from django import forms
class PostForm(forms.ModelForm): # Django๊ฐ ์ ๊ณตํ๋ ํด๋์ค ์์
class Meta:
model = Post
fields = ['title', 'content']
ModelForm์ด ์๋์ผ๋ก ํด์ฃผ๋ ๊ฒ
| ๊ธฐ๋ฅ | ์ค๋ช |
|---|---|
| ํ๋ ์๋ ์์ฑ | ๋ชจ๋ธ์ ํ๋๋ฅผ ์๋์ผ๋ก HTML <input>์ผ๋ก ๋ณํ |
| ์ ํจ์ฑ ๊ฒ์ฌ | ์ ๋ ฅ๊ฐ์ด ์ฌ๋ฐ๋ฅธ์ง ์๋ ๊ฒ์ฆ |
| DB ์ ์ฅ | .save() ํ ์ค๋ก DB์ ๋ฐ๋ก ์ ์ฅ |
์ง์ ๋ง๋ค ๋ vs ModelForm ๋น๊ต
# โ ์ง์ ๋ง๋ค ๋ (๊ธธ๊ณ ๋ณต์ก)
<input type="text" name="title">
<input type="text" name="content">
# ์ ํจ์ฑ ๊ฒ์ฌ๋ ์ง์ ์์ฑ...
# DB ์ ์ฅ๋ ์ง์ ์์ฑ...
# โ
ModelForm ์ฌ์ฉ (๊ฐ๋จ!)
form = PostForm() # ๋!
form.save() # DB ์ ์ฅ๋ ํ ์ค!
๊ฒฐ๋ก
Django ๋ด์ฅ ํด๋์ค โ
๋ณ๋ ์ค์น ๋ถํ์ โ
from django import forms ๋ก ๋ฐ๋ก ์ฌ์ฉ ๊ฐ๋ฅ โ
๐ก Django๊ฐ ๋ฐ๋ณต์ ์ธ ํผ ์์ ์ ์๋ํํด์ฃผ๊ธฐ ์ํด ๋ง๋ ๊ฐ๋ ฅํ ๋ด์ฅ ๊ธฐ๋ฅ์ ๋๋ค!
์ฌ์ฉ์๊ฐ ํผ์ ๋ฐ์ดํฐ ์
๋ ฅ โ DB์ ์ ๋ฐ์ดํฐ ์ ์ฅ
์) ๊ฒ์๊ธ ์์ฑ, ํ์๊ฐ์
์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ ๊ธฐ๋ฅ
๋ชฉ๋ก์์ ํญ๋ชฉ ํด๋ฆญ โ ํด๋น ๋ฐ์ดํฐ ์์ธ ๋ด์ฉ ํ์
์) ๊ฒ์๊ธ ๋ณธ๋ฌธ ๋ณด๊ธฐ
ํน์ ๋ฐ์ดํฐ ํ๋๋ฅผ ์์ธํ ์กฐํํ๋ ๊ธฐ๋ฅ
๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ ํผ์ ํ์ โ ์์ ํ ์ ์ฅ
์) ๊ฒ์๊ธ ํธ์ง
๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ธฐ๋ฅ
ํน์ ๋ฐ์ดํฐ ์ ํ โ DB์์ ์์ ์ญ์
์) ๊ฒ์๊ธ ์ญ์
๋ฐ์ดํฐ๋ฅผ DB์์ ์ ๊ฑฐํ๋ ๊ธฐ๋ฅ
๋ฐ์ดํฐ๊ฐ ๋ง์ ๋ โ ํ ํ์ด์ง์ n๊ฐ์ฉ ๋๋ ์ ํ์
์) 1ํ์ด์ง, 2ํ์ด์ง, 3ํ์ด์ง...
๋ง์ ๋ฐ์ดํฐ๋ฅผ ๋๋ ์ ๋ณด์ฌ์ฃผ๋ ๊ธฐ๋ฅ
ModelForm โ ์
๋ ฅ ํผ ์๋ ์์ฑ
Create (์์ฑ) โ ๋ฐ์ดํฐ ์ถ๊ฐ (INSERT)
Detail (์์ธ) โ ๋ฐ์ดํฐ 1๊ฐ ์กฐํ (SELECT)
Update (์์ ) โ ๋ฐ์ดํฐ ๋ณ๊ฒฝ (UPDATE)
Delete (์ญ์ ) โ ๋ฐ์ดํฐ ์ ๊ฑฐ (DELETE)
Pagination โ ๋ฐ์ดํฐ ๋ถํ ํ์
๐ก ์ด 6๊ฐ์ง๊ฐ ํฉ์ณ์ง๋ฉด ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฐ CRUD ์์ฑ์ ๋๋ค!
Django์์ ๋ทฐ๋ฅผ ํจ์๋ก ์์ฑํ๋ ๋ฐฉ์์ด์์.
# views.py
from django.shortcuts import render
def study_list(request):
studies = Study.objects.all()
return render(request, 'study/list.html', {'studies': studies})
# โ FBV
def study_list(request):
studies = Study.objects.all()
return render(request, 'study/list.html', {'studies': studies})
# โ
CBV
class StudyListView(ListView):
model = Study
template_name = 'study/list.html'
| FBV | CBV | |
|---|---|---|
| ๊ตฌ์กฐ | ํจ์ | ํด๋์ค |
| ๋์ด๋ | ์ฌ์ | ์ด๋ ค์ |
| ์ฝ๋๋ | ๋ง์ | ์ ์ |
| ์ ์ฐ์ฑ | ๋์ | ๋ฎ์ |
from django.shortcuts import render, get_object_or_404
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
ํน์ง
if request.method == 'POST':)from django.views import View
class PostDetailView(View):
def get(self, request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
def post(self, request, pk):
# POST ์์ฒญ ์ฒ๋ฆฌ
...
ํน์ง
CBV๋ฅผ ๋ ์ถ์ํํ ๊ฒ์ผ๋ก, Django๊ฐ CRUD ํจํด์ ๋ฏธ๋ฆฌ ๊ตฌํํด ๋์ ๋ทฐ
from django.views.generic import ListView, DetailView, CreateView
class PostListView(ListView):
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
class PostDetailView(DetailView):
model = Post
class PostCreateView(CreateView):
model = Post
fields = ['title', 'content']
success_url = '/posts/'
์ฃผ์ ์ข ๋ฅ
| ํด๋์ค | ์ฉ๋ |
|---|---|
ListView | ๋ชฉ๋ก ์กฐํ |
DetailView | ๋จ์ผ ๊ฐ์ฒด ์กฐํ |
CreateView | ๊ฐ์ฒด ์์ฑ |
UpdateView | ๊ฐ์ฒด ์์ |
DeleteView | ๊ฐ์ฒด ์ญ์ |
TemplateView | ๋จ์ ํ ํ๋ฆฟ ๋ ๋๋ง |
| ๊ตฌ๋ถ | ํจ์๋ทฐ (FBV) | ํด๋์ค๋ทฐ (CBV) | ์ ๋๋ฆญ๋ทฐ |
|---|---|---|---|
| ๊ตฌ์กฐ | ํจ์ | ํด๋์ค | ํด๋์ค (CBV ํ์ฅ) |
| ์ฝ๋๋ | ๋ง์ | ์ค๊ฐ | ๋งค์ฐ ์ ์ |
| ๊ฐ๋ ์ฑ | ์ง๊ด์ | ๊ตฌ์กฐ์ | ์ ์ธ์ |
| ์ฌ์ฌ์ฉ์ฑ | ๋ฎ์ | ๋์ | ๋งค์ฐ ๋์ |
| ์ ์ฐ์ฑ | ๋งค์ฐ ๋์ | ๋์ | ๋ฎ์ (์ปค์คํฐ๋ง์ด์ง ํ์) |
| ์ ํฉํ ๊ฒฝ์ฐ | ๋จ์/ํน์ ๋ก์ง | ๋ณต์กํ ๋ก์ง | ํ์ค CRUD |
์ค๋ฌด์์๋ ์ธ ๊ฐ์ง๋ฅผ ์ํฉ์ ๋ง๊ฒ ํผ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค.
FBV
def post_create(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.save()
return redirect('post_list')
else:
form = PostForm()
return render(request, 'post_form.html', {'form': form})
CBV
class PostCreateView(View):
def get(self, request):
form = PostForm()
return render(request, 'post_form.html', {'form': form})
def post(self, request):
form = PostForm(request.POST)
if form.is_valid():
form.save()
return redirect('post_list')
return render(request, 'post_form.html', {'form': form})
์ ๋๋ฆญ๋ทฐ
class PostCreateView(CreateView):
model = Post
fields = ['title', 'content']
success_url = '/posts/'
# GET/POST ์ฒ๋ฆฌ, form ์์ฑ, ์ ํจ์ฑ ๊ฒ์ฌ, ์ ์ฅ, ๋ฆฌ๋ค์ด๋ ํธ โ ๋ชจ๋ ์๋
FBV
# ๋ชฉ๋ก
def post_list(request):
posts = Post.objects.all()
return render(request, 'post_list.html', {'posts': posts})
# ์์ธ
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'post_detail.html', {'post': post})
CBV
class PostListView(View):
def get(self, request):
posts = Post.objects.all()
return render(request, 'post_list.html', {'posts': posts})
class PostDetailView(View):
def get(self, request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'post_detail.html', {'post': post})
์ ๋๋ฆญ๋ทฐ
class PostListView(ListView):
model = Post
# Post.objects.all() ์๋ ์คํ, 'post_list.html' ์๋ ํ์
class PostDetailView(DetailView):
model = Post
# pk๋ก ๊ฐ์ฒด ์๋ ์กฐํ, ์์ผ๋ฉด 404 ์๋ ์ฒ๋ฆฌ
FBV
def post_update(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == 'POST':
form = PostForm(request.POST, instance=post) # โ instance ์ง์ ๋๊ฒจ์ผ ํจ
if form.is_valid():
form.save()
return redirect('post_detail', pk=pk)
else:
form = PostForm(instance=post)
return render(request, 'post_form.html', {'form': form})
CBV
class PostUpdateView(View):
def get(self, request, pk):
post = get_object_or_404(Post, pk=pk)
form = PostForm(instance=post)
return render(request, 'post_form.html', {'form': form})
def post(self, request, pk):
post = get_object_or_404(Post, pk=pk)
form = PostForm(request.POST, instance=post)
if form.is_valid():
form.save()
return redirect('post_detail', pk=pk)
return render(request, 'post_form.html', {'form': form})
์ ๋๋ฆญ๋ทฐ
class PostUpdateView(UpdateView):
model = Post
fields = ['title', 'content']
success_url = '/posts/'
# ๊ธฐ์กด ๋ฐ์ดํฐ ์๋ ๋ฐ์ธ๋ฉ, ์ ํจ์ฑ ๊ฒ์ฌ, ์ ์ฅ ๋ชจ๋ ์๋
FBV
def post_delete(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == 'POST':
post.delete()
return redirect('post_list')
return render(request, 'post_confirm_delete.html', {'post': post})
CBV
class PostDeleteView(View):
def get(self, request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'post_confirm_delete.html', {'post': post})
def post(self, request, pk):
post = get_object_or_404(Post, pk=pk)
post.delete()
return redirect('post_list')
์ ๋๋ฆญ๋ทฐ
class PostDeleteView(DeleteView):
model = Post
success_url = '/posts/'
# ํ์ธ ํ์ด์ง ๋ ๋๋ง โ POST ์์ โ ์ญ์ โ ๋ฆฌ๋ค์ด๋ ํธ ์๋
FBV
์์ฒญ โ if method == 'POST' ๋ถ๊ธฐ โ ์ง์ ํผ/์ฟผ๋ฆฌ ์ฒ๋ฆฌ โ ์๋ต
CBV
์์ฒญ โ dispatch() โ get() / post() ์๋ ๋ถ๊ธฐ โ ์ฒ๋ฆฌ โ ์๋ต
์ ๋๋ฆญ๋ทฐ
์์ฒญ โ dispatch() โ get_object() / get_form() ์๋ ์คํ
โ form_valid() / form_invalid() ์๋ ๋ถ๊ธฐ โ ์๋ต
| ํต์ฌ | |
|---|---|
| FBV | ๋ชจ๋ ํ๋ฆ์ ๋ด๊ฐ ์ง์ ์์ฑ |
| CBV | HTTP ๋ฉ์๋ ๋ถ๊ธฐ๋ฅผ Django๊ฐ ์ฒ๋ฆฌ, ๋๋จธ์ง๋ ์ง์ |
| ์ ๋๋ฆญ๋ทฐ | CRUD ํ๋ฆ ์ ์ฒด๋ฅผ Django๊ฐ ์ฒ๋ฆฌ, ๋๋ ์ค์ ๋ง |
"์ฌ์ฉ์๊ฐ ์น์์ ๋ญ๊ฐ ์ ๋ ฅํ์ ๋, Django ๋ด๋ถ์์ ์ด๋ค ์์๋ก ์ฒ๋ฆฌ๋๋๊ฐ" ๋ฅผ ์ดํดํ๋ ๊ฒ์ ๋๋ค.
๋ธ๋ผ์ฐ์ (ํฌ๋กฌ ๋ฑ)์ ์๋ฒ(Django)๋ ํธ์ง๋ฅผ ์ฃผ๊ณ ๋ฐ๋ฏ ํต์ ํฉ๋๋ค.
๋ธ๋ผ์ฐ์ โ (์์ฒญ, Request) โ Django ์๋ฒ
๋ธ๋ผ์ฐ์ โ (์๋ต, Response) โ Django ์๋ฒ
์์ฒญ์๋ ๋ ์ข ๋ฅ๊ฐ ์์ด์:
Django์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ค๋ฉด ๋ชจ๋ธ(Model) ์ด๋ผ๋ ์ค๊ณ๋๊ฐ ํ์ํฉ๋๋ค.
# ์์: ๊ฒ์๊ธ ๋ชจ๋ธ
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
ModelForm์ ์ด ๋ชจ๋ธ์ ๊ธฐ๋ฐ์ผ๋ก HTML ์ ๋ ฅ ํผ์ ์๋ ์์ฑ + ๊ฒ์ฆํด์ฃผ๋ ๋๊ตฌ์ ๋๋ค.
๋ชจ๋ธ(DB ์ค๊ณ๋) โ ModelForm โ HTML ํผ ์๋ ์์ฑ
โ ์
๋ ฅ๊ฐ ์๋ ๊ฒ์ฆ
โ DB ์ ์ฅ๊น์ง ํ ๋ฒ์
์ง์ HTML <input> ํ๊ทธ๋ฅผ ํ๋์ฉ ๋ง๋ค๊ณ , ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ผ์ผ์ด ์ง์ง ์์๋ ๋๋ค๋ ๊ฒ ํต์ฌ์
๋๋ค.
์ด๋ฏธ์ง์ ๋์จ ํ๋ฆ์ ์ค์ํ๋ก ๋น์ ํ๋ฉด:
| ํ๋ฆ | ๋น์ |
|---|---|
| ์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ์์ ๊ฐ ์ ๋ ฅ | ์ข ์ด ์ ์ฒญ์์ ๋ด์ฉ์ ์ |
| Django View๊ฐ POST ์์ฒญ ๋ฐ์ | ์ ์ ์ฐฝ๊ตฌ๊ฐ ์ ์ฒญ์๋ฅผ ๋ฐ์ |
| ModelForm์ด ๊ฒ์ฆ | ๋ด๋น์๊ฐ ๋น ์ง ํญ๋ชฉ ์๋์ง ํ์ธ |
| ๋ชจ๋ธ์ ์ ์ฅ | ์๋ฅ๋ฅผ DB ์บ๋น๋์ ๋ณด๊ด |
| redirect๋ก ํ๋ฉด ์ด๋ | "์ ์ ์๋ฃ๋์ต๋๋ค" ์๋ด ํ์ด์ง๋ก ์ด๋ |
| ๋ชฉ๋ก/์์ธ ํ์ด์ง์์ ๊ฒฐ๊ณผ ํ์ธ | ์ ์๋ ๋ด์ฉ์ ํ๋ฉด์์ ์กฐํ |
# views.py
def post_create(request):
# GET ์์ฒญ โ ๋น ํผ์ ๋ณด์ฌ์ค
if request.method == 'GET':
form = PostForm()
return render(request, 'create.html', {'form': form})
# POST ์์ฒญ โ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌ
if request.method == 'POST':
form = PostForm(request.POST) # โ ์
๋ ฅ๊ฐ ๋ฐ๊ธฐ
if form.is_valid(): # โก ๊ฒ์ฆ
form.save() # โข DB ์ ์ฅ
return redirect('post_list') # โฃ ๋ค๋ฅธ ํ์ด์ง๋ก ์ด๋
# ๊ฒ์ฆ ์คํจ ์ โ ์๋ฌ์ ํจ๊ป ํผ ๋ค์ ๋ณด์ฌ์ค
return render(request, 'create.html', {'form': form})
http://velog.io/@hy_1023/%ED%95%A8%EC%88%98-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%A0%9C%EB%84%88%EB%A6%AD
์ด๋ฏธ์ง ๋งจ ์๋ ๋ฌธ์ฅ์ด ํต์ฌ์ ๋งํด์ค๋๋ค.
"์ด ํ๋ฆ์ด ์ดํด๋์ด์ผ โ ํด๋์คํ View โ ์ ๋๋ฆญ View โ DRF๋ก ์์ฐ์ค๋ฝ๊ฒ ์ฐ๊ฒฐ๋๋ค"
์ฆ, Django๋ฅผ ๋ฐฐ์ฐ๋ ์์๊ฐ:
ํจ์ํ View๋ก ํ๋ฆ ์ดํด
โ
ํด๋์คํ View (์ฝ๋๋ฅผ ๋ ์งง๊ฒ)
โ
์ ๋๋ฆญ View (CRUD๋ฅผ ์๋ํ)
โ
DRF (API ์๋ฒ ๊ฐ๋ฐ)
์ง๊ธ ๋ฐฐ์ฐ๋ ๊ฒ ๋ชจ๋ ๊ฒ์ ๋ฟ๋ฆฌ์ด๊ธฐ ๋๋ฌธ์, ์ฝ๋ ํ ์ค์ฉ ์ธ์ฐ๊ธฐ๋ณด๋ค "์์ฒญ โ ๊ฒ์ฆ โ ์ ์ฅ โ ์ด๋" ์ด 4๋จ๊ณ ํ๋ฆ์ ๋จธ๋ฆฟ์์ ๊ทธ๋ฆด ์ ์๋ ๊ฒ ์ง์ง ๋ชฉํ์ ๋๋ค.
Django View์ ํ์ฅ์ฑ์ด๋, ๊ฒฐ๊ตญ ๊ฐ์ "์์ฒญ โ ์๋ต" ๊ตฌ์กฐ๋ฅผ ์ ์ ๋ ์ ์ ์ฝ๋๋ก, ๋ ๋ง์ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ๋๋ก ๋ฐ์ ์ํค๋ ๊ณผ์ ์ ๋๋ค.
์คํฌ๋ฆฐ์ท์ ๋์จ ํ์ต ์์๊ฐ ๋ฐ๋ก ๊ทธ ํ์ฅ์ ํ๋ฆ์ด์์.
1๋จ๊ณ: ํจ์ํ View (FBV) โ ๋ชจ๋ ๊ฒ์ ์ง์ ์ด๋ค
def post_list(request):
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
์์ฒญ์ ๋ฐ๊ณ , ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ด๊ณ , ํ ํ๋ฆฟ์ ๋๊ธฐ๋ ๊ณผ์ ์ ํ ์ค ํ ์ค ์ง์ ์์ฑํฉ๋๋ค. ๊ฐ์ฅ ๋ช ์์ ์ด๊ณ ์ดํดํ๊ธฐ ์ฝ์ง๋ง, ๋น์ทํ View๊ฐ ๋์ด๋๋ฉด ๋ฐ๋ณต ์ฝ๋๊ฐ ๋ง์์ง๋๋ค.
2๋จ๊ณ: ํด๋์คํ View (CBV) โ ๋ฐ๋ณต์ ๊ตฌ์กฐ๋ก ์ค์ธ๋ค
from django.views import View
class PostListView(View):
def get(self, request):
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
def post(self, request):
# POST ์ฒ๋ฆฌ
...
FBV์์ if request.method == 'GET' ๊ฐ์ ๋ถ๊ธฐ๋ฅผ ๋ฉ์๋ ์ด๋ฆ(get, post)์ผ๋ก ์๋ ๋ถ๋ฆฌํด์ค๋๋ค. ํต์ฌ์ ์์์ด ๊ฐ๋ฅํด์ง๋ค๋ ์ ์ด์์. ๊ณตํต ๋ก์ง์ ๋ถ๋ชจ ํด๋์ค์ ๋๊ณ ์์์ด ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
3๋จ๊ณ: ์ ๋๋ฆญ View โ "๋ชฉ๋ก ๋ณด์ฌ์ค", "ํ๋ ๋ง๋ค์ด์ค"๋ฅผ ํ ์ค๋ก
from django.views.generic import ListView
class PostListView(ListView):
model = Post
template_name = 'blog/post_list.html'
Django๊ฐ "๋ชฉ๋ก ์กฐํ"์ ํ์ํ ๋ก์ง(DB ์กฐํ, ํ์ด์ง๋ค์ด์
, ํ
ํ๋ฆฟ ์ ๋ฌ)์ ์ด๋ฏธ ๋ค ๋ง๋ค์ด๋๊ณ , ์ฌ๋ฌ๋ถ์ ๋ฌด์์(model), ์ด๋์(template_name) ๋ณด์ฌ์ค์ง๋ง ์๋ ค์ฃผ๋ฉด ๋ฉ๋๋ค. CreateView, UpdateView, DeleteView ๋ฑ CRUD ์ ์ฒด๊ฐ ์ด๋ฐ ์์ผ๋ก ์ ๊ณต๋ฉ๋๋ค.
4๋จ๊ณ: DRF (Django REST Framework) โ HTML ๋์ JSON์ ๋ฐํ
from rest_framework.generics import ListAPIView
class PostListAPI(ListAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
๊ตฌ์กฐ๋ ์ ๋๋ฆญ View์ ๊ฑฐ์ ๊ฐ์๋ฐ, ํ ํ๋ฆฟ ๋์ Serializer๊ฐ ๋ฐ์ดํฐ๋ฅผ JSON์ผ๋ก ๋ณํํฉ๋๋ค. ํ๋ก ํธ์๋(React, ๋ชจ๋ฐ์ผ ์ฑ ๋ฑ)์ ํต์ ํ๋ API ์๋ฒ๋ฅผ ๋ง๋ค ๋ ์ฐ์ ๋๋ค.
์ ๋ฆฌํ๋ฉด ์ด ๋ค ๋จ๊ณ๋ ๋ณ๊ฐ์ ๊ธฐ์ ์ด ์๋๋ผ, ๊ฐ์ ํจํด์ ์ ์ ์ถ์ํํ ๊ฒ์ ๋๋ค.
| ๋จ๊ณ | ์ง์ ์์ฑํ๋ ๊ฒ | Django๊ฐ ๋์ ํด์ฃผ๋ ๊ฒ |
|---|---|---|
| FBV | ์ ๋ถ | ์์ |
| CBV | ๋น์ฆ๋์ค ๋ก์ง | ๋ฉ์๋ ๋ถ๊ธฐ |
| ์ ๋๋ฆญ View | ์ค์ ๊ฐ๋ง | CRUD ๋ก์ง ์ ์ฒด |
| DRF | ์ค์ ๊ฐ๋ง | CRUD + JSON ์ง๋ ฌํ |
๊ทธ๋์ ๋ฌธ์์์ ๋งํ ๊ฒ์ฒ๋ผ FBV์ "์์ฒญ โ ๊ฒ์ฆ โ ์ ์ฅ โ ์ด๋" ํ๋ฆ์ ๋จผ์ ์ฒด๊ฐํ๋ ๊ฒ ์ค์ํฉ๋๋ค. ๋๋จธ์ง๋ ๊ทธ ํ๋ฆ์ ์๋ํํ ๊ฒ์ ๋ถ๊ณผํ๋๊น์.
Django์ ํจ์ํ View(Function-Based View, FBV)์ ๋ํด ์ค๋ช ๋๋ฆด๊ฒ์.
ํจ์ํ View๋ HTTP ์์ฒญ(request)์ ๋ฐ์์ HTTP ์๋ต(response)์ ๋ฐํํ๋ ๋จ์ํ Python ํจ์์
๋๋ค.
# ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํํ
def post_list(request):
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
urls.py์์ ์ด๋ ๊ฒ ์ฐ๊ฒฐํฉ๋๋ค:
path('posts/', views.post_list, name='post_list')
ํ๋์ ํจ์์์ GET/POST๋ฅผ ๋์์ ์ฒ๋ฆฌํ๋ ํจํด์ด ์ค๋ฌด์์ ๋งค์ฐ ํํฉ๋๋ค.
def post_create(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.save()
return redirect('post_list')
else: # GET
form = PostForm()
return render(request, 'blog/post_form.html', {'form': form})
ํด๋์คํ View์์๋ mixin์ผ๋ก ํด๊ฒฐํ๋ ๊ฒ์ FBV์์๋ ๋ฐ์ฝ๋ ์ดํฐ๋ก ๊ฐ๊ฒฐํ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods, require_POST
from django.views.decorators.csrf import csrf_exempt
# ๋ก๊ทธ์ธ ํ์
@login_required
def my_page(request):
return render(request, 'my_page.html')
# ํ์ฉํ HTTP ๋ฉ์๋ ์ ํ
@require_http_methods(["GET", "POST"])
def post_edit(request, pk):
...
# POST๋ง ํ์ฉ
@require_POST
def post_delete(request, pk):
...
# ๋ฐ์ฝ๋ ์ดํฐ ์ค์ฒฉ๋ ๊ฐ๋ฅ
@login_required
@require_POST
def comment_delete(request, pk):
...
ํ ํ๋ฆฟ ๋ ๋๋ง ์์ด JSON API ์๋ํฌ์ธํธ๋ก ํ์ฉํ ์ ์์ต๋๋ค.
from django.http import JsonResponse
def api_post_list(request):
posts = Post.objects.values('id', 'title', 'created_at')
return JsonResponse(list(posts), safe=False)
# AJAX ์์ฒญ ์ฒ๋ฆฌ
@require_POST
def api_like_toggle(request, pk):
post = get_object_or_404(Post, pk=pk)
post.likes += 1
post.save()
return JsonResponse({'likes': post.likes})
๋ฐ๋ณต๋๋ ๋ก์ง์ ๋ฐ์ฝ๋ ์ดํฐ๋ก ์ถ์ถํ๋ ๊ฒ์ด FBV์ ๊ฐ๋ ฅํ ํจํด์ ๋๋ค.
from functools import wraps
from django.http import HttpResponseForbidden
# ์์ฑ์ ๋ณธ์ธ๋ง ํ์ฉํ๋ ์ปค์คํ
๋ฐ์ฝ๋ ์ดํฐ
def author_only(view_func):
@wraps(view_func)
def wrapper(request, pk, *args, **kwargs):
post = get_object_or_404(Post, pk=pk)
if post.author != request.user:
return HttpResponseForbidden("๊ถํ์ด ์์ต๋๋ค.")
return view_func(request, pk, *args, **kwargs)
return wrapper
@login_required
@author_only
def post_edit(request, pk):
# ์ฌ๊ธฐ ๋๋ฌํ๋ฉด ์ด๋ฏธ ์์ฑ์ ๋ณธ์ธ์ด ๋ณด์ฅ๋จ
...
def post_list(request):
# ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ก ํํฐ๋ง/์ ๋ ฌ/ํ์ด์ง๋ค์ด์
search = request.GET.get('q', '')
sort = request.GET.get('sort', '-created_at')
page = request.GET.get('page', 1)
posts = Post.objects.all()
if search:
posts = posts.filter(title__icontains=search)
posts = posts.order_by(sort)
paginator = Paginator(posts, 10)
page_obj = paginator.get_page(page)
return render(request, 'blog/post_list.html', {
'page_obj': page_obj,
'search': search,
'sort': sort,
})
| ์ํฉ | ์ถ์ฒ |
|---|---|
| ๋จ์ํ CRUD | CBV (ListView, CreateView ๋ฑ) |
| ๋ณต์กํ ๋น์ฆ๋์ค ๋ก์ง | FBV โ ํ๋ฆ์ด ๋์ ๋ณด์ฌ์ ๋๋ฒ๊น ์ด ์ฌ์ |
| ์ฌ๋ฌ ๋ชจ๋ธ์ ํ View์์ ์ฒ๋ฆฌ | FBV โ ์์ ๋๊ฐ ๋์ |
| API ์๋ํฌ์ธํธ | FBV (๋๋ DRF) |
ํต์ฌ์ FBV๊ฐ "๋จ์ํ ๊ฒ"์ด ์๋๋ผ, ๋ฐ์ฝ๋ ์ดํฐ ์กฐํฉ๊ณผ ์์ ๋ก์ด ๋ก์ง ๊ตฌ์ฑ์ด ๊ฐ๋ฅํ๋ค๋ ์ ์์ ์คํ๋ ค ๋ณต์กํ ์๊ตฌ์ฌํญ์ ๋ ์ ์ฐํ๋ค๋ ๊ฒ์ ๋๋ค. ๊ถ๊ธํ ๋ถ๋ถ์ด ์์ผ๋ฉด ๋ ๊น์ด ๋ค์ด๊ฐ ๋ณผ ์ ์์ด์.
์ง๋ฌธ>์ฐ์ 4๋จ๊ณ๊ฐ ์ดํด๊ฐ ์๊ฐ๊ณ ๊ทธ์ค์ redirect์ ์ญํ ๊ณผ ์๋ฏธ๋ฅผ ์๊ณ ์ถ์ด. ๋ํ 4๋จ๊ณ์์ ๋์จ ์ฝ๋๋ฅผ ๋ถ์๊ณผ ํฐ ํ๋ฆ๋๋ก ๋๋ ์ ์ด๋์ญํ ์ ํ๋์ง ์๋ ค์ค ๊ทธ๋ฆฌ๊ณ 3๋จ๊ณ์์ ์ฒ๋ฆฌํ๋ ํ๋ฆ์๋ํด ๋์ฝ๊ฒ ํํํด์ค
๋ต๋ณ>
์ค์ํ ๋น์ ๋ก ๋ณด๋ฉด:
์ํ ์ฐฝ๊ตฌ์์ ์๋ฅ ์ ์ถ ์๋ฃ ํ,
์ง์์ด "์ ์ ์๋ฃ๋์ต๋๋ค. ์ ์ชฝ ๋๊ธฐ์ค๋ก ๊ฐ์ธ์" ๋ผ๊ณ ์๋ดํ๋ ๊ฒ
๋ง์ฝ redirect๊ฐ ์๋ค๋ฉด?
์ฌ์ฉ์๊ฐ ๊ธ ์ ์ฅ โ ๊ทธ ์๋ฆฌ์ ๋ฉ์ถค
โ ์๋ก๊ณ ์นจ ๋๋ฅด๋ฉด โ ๊ธ์ด ๋ ์ ์ฅ๋จ (์ค๋ณต ์ ์ฅ ๋ฐ์!)
redirect๊ฐ ์์ผ๋ฉด?
์ฌ์ฉ์๊ฐ ๊ธ ์ ์ฅ โ "๋ชฉ๋ก ํ์ด์ง๋ก ๊ฐ์ธ์" ๋ช
๋ น
โ ์๋ก๊ณ ์นจ ๋๋ฌ๋ โ ๋ชฉ๋ก ํ์ด์ง๋ง ์๋ก๊ณ ์นจ (์ค๋ณต ์ ์ฅ ์์)
์ฆ redirect์ ์ญํ ์ ๋ ๊ฐ์ง์ ๋๋ค.
์ฝ๋๋ฅผ ํฐ ๋ฉ์ด๋ฆฌ 3๊ฐ๋ก ๋๋ ์ ์์ต๋๋ค.
def post_create(request):
# โ ์ด ํจ์ ์ ์ฒด๊ฐ ํ๋์ "์ ์ ์ฐฝ๊ตฌ" ์ญํ
if request.method == 'GET':
# โ ์ฌ์ฉ์๊ฐ ๊ทธ๋ฅ ํ์ด์ง๋ฅผ ์ด์์ ๋ (์กฐํ ์์ฒญ)
form = PostForm()
# โ ์๋ฌด๊ฒ๋ ์ ์ฑ์์ง ๋น ํผ์ ๋ง๋ ๋ค
return render(request, 'create.html', {'form': form})
# โ ๊ทธ ๋น ํผ์ HTML๋ก ๊ทธ๋ ค์ ๋ธ๋ผ์ฐ์ ์ ๋ณด๋ด์ค
๐ก ์ฌ์ฉ์ ์ ์ฅ: ์ฃผ์์ฐฝ์ URL ์ ๋ ฅ โ ๋น ์ ๋ ฅ ํผ ํ๋ฉด์ด ์ด๋ฆผ
if request.method == 'POST':
# โ ์ฌ์ฉ์๊ฐ ํผ์ ๋ด์ฉ์ ์ฐ๊ณ "์ ์ถ" ๋ฒํผ์ ๋๋ ์ ๋
form = PostForm(request.POST)
# โ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๋ฐ์ดํฐ๋ฅผ ํผ์ ๋ด๋๋ค
# (์์ง ์ ์ฅ์ ์ ํจ. ๊ฒ์ฌํ ์ค๋น๋ง ํ ์ํ)
if form.is_valid():
# โ "์ด ๋ฐ์ดํฐ ๊ด์ฐฎ์?" ๊ฒ์ฌ
# ์) ์ ๋ชฉ์ด ๋น์ด์์ง ์์์ง, ๊ธ์์ ์ด๊ณผ๋ ์๋์ง
form.save()
# โ ๊ฒ์ฌ ํต๊ณผ โ DB์ ์ ์ฅ
return redirect('post_list')
# โ ์ ์ฅ ์๋ฃ โ ๋ชฉ๋ก ํ์ด์ง๋ก ๊ฐ์ ์ด๋
๐ก ์ฌ์ฉ์ ์ ์ฅ: ๋ด์ฉ ์ ๋ ฅ ํ ์ ์ถ โ ์ ์ฅ ์๋ฃ โ ๋ชฉ๋ก ํ์ด์ง๋ก ์ด๋๋จ
return render(request, 'create.html', {'form': form})
# โ is_valid() ์คํจํ์ ๋ ์ฌ๊ธฐ๋ก ์ด
# ์๋ฌ ๋ฉ์์ง๊ฐ ๋ด๊ธด ํผ์ ๋ค์ ํ๋ฉด์ ๋ณด์ฌ์ค
๐ก ์ฌ์ฉ์ ์ ์ฅ: ์ ๋ชฉ์ ์ ์ฐ๊ณ ์ ์ถ โ "์ ๋ชฉ์ ์ ๋ ฅํ์ธ์" ์๋ฌ ํ์์ ํจ๊ป ํผ์ผ๋ก ๋์์ด
์ฌ์ฉ์๊ฐ URL ์ ์
โ
GET ์์ฒญ? โโโโโโโ ๋น ํผ ํ๋ฉด ๋ณด์ฌ์ค
โ
์ฌ์ฉ์๊ฐ ๋ด์ฉ ์
๋ ฅ ํ ์ ์ถ
โ
POST ์์ฒญ? โโโโโโโ ๋ฐ์ดํฐ ๋ฐ์
โ
is_valid() ๊ฒ์ฌ
โ โ
์คํจ ์ฑ๊ณต
โ โ
์๋ฌ ํผ ๋ค์ ๋ณด์ฌ์ค DB์ ์ ์ฅ
โ
redirect โ ๋ชฉ๋ก ํ์ด์ง
| Django ํ๋ฆ | ํธ์์ ๋น์ |
|---|---|
| ์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ์์ ๊ฐ ์ ๋ ฅ | ์๋์ด ์ฃผ๋ฌธ์์ ๋ฉ๋ด๋ฅผ ์ |
| POST ์์ฒญ ๋ฐ์ | ์๋ฐ์์ด ์ฃผ๋ฌธ์๋ฅผ ๋ฐ์๋ค์ |
| ModelForm์ด ๊ฒ์ฆ | "ํ์ ๋ฉ๋ด ์๋์ง, ๋น ์ง ํญ๋ชฉ ์๋์ง" ํ์ธ |
| โ ํต๊ณผ โ ๋ชจ๋ธ์ ์ ์ฅ | ์ด์ ์์ผ๋ฉด ์ฃผ๋ฐฉ์ ์ฃผ๋ฌธ ์ ๋ฌ + ์์์ฆ ์ถ๋ ฅ |
| โ ์คํจ โ ํผ ๋ค์ ๋ณด์ฌ์ค | "์ด ๋ฉ๋ด๋ ์์ด์, ๋ค์ ๊ณจ๋ผ์ฃผ์ธ์" |
| redirect | "์ฃผ๋ฌธ ์๋ฃ! ์ ์ชฝ ํฝ์ ๋๊ธฐ์ค๋ก ๊ฐ์ธ์" |
| ๋ชฉ๋ก/์์ธ ํ์ด์ง | ํฝ์ ํ๋ฉด์์ ๋ด ์ฃผ๋ฌธ ํ์ธ |
ํต์ฌ๋ง ๊ธฐ์ตํ๋ฉด ๋ฉ๋๋ค:
GET = ๋ณด์ฌ์ฃผ๊ธฐ / POST = ์ฒ๋ฆฌํ๊ธฐ / redirect = ๋ค์ ์ฅ์๋ก ๋ณด๋ด๊ธฐ
์ด ์ธ ๊ฐ์ง๊ฐ ์น์ ๋ชจ๋ ๋์์ ๊ธฐ๋ณธ์ ๋๋ค. ๋ ๊ถ๊ธํ ๋ถ๋ถ ์์ผ๋ฉด ๋ง์ํด ์ฃผ์ธ์!
https://velog.io/@hy_1023/GET-vs-POST-%EC%B0%A8%EC%9D%B4
ํ๋๋ ๋ฌด์์ด๊ณ ๋ชจ๋ธ์ด๋ ๊ทธ๋ฆ ๊ทธ๋ฆฌ๊ณ ๊ทธ์์ ๋ฐ์ดํฐ.. ๊ฐ๋ ์์ ๋ ํ์ฅํ์ฌ ํฐํ๋ฆ๊ตฌ์กฐ์ ์ผ๋ก ์ดํด์์ผ์ค
Django์ ํฐ ํ๋ฆ์ ๊ฑด๋ฌผ ์ง๊ธฐ์ ๋น์ ํด์ ์ค๋ช ํด ๋ณผ๊ฒ์.
Model์ "์ค๊ณ๋"์ ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ด ์ด๋ค ๊ตฌ์กฐ๋ก ์๊ฒจ์ผ ํ๋์ง๋ฅผ Python ์ฝ๋๋ก ์ ์ธํ๋ ๊ฒ๋๋ค.
class Study(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
์ด ์ฝ๋๋ฅผ ์ฐ๋ ์๊ฐ, Django๋ ์ด๋ ๊ฒ ์ดํดํฉ๋๋ค:
"์, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ study๋ผ๋ ํ ์ด๋ธ์ ๋ง๋ค์ด์ผ ํ๋๊ตฌ๋. ์นธ(column)์ title, content, created_at ์ธ ๊ฐ๊ณ , ๊ฐ๊ฐ ์งง์ ๋ฌธ์์ด, ๊ธด ๋ฌธ์์ด, ๋ ์ง ํ์์ด๊ตฌ๋."
Field๋ ๊ทธ ์ค๊ณ๋ ์์ "์นธ ํ๋ํ๋"์
๋๋ค. title, content, created_at ๊ฐ๊ฐ์ด ํ๋์์. ํ๋๋ ๋จ์ํ ์ด๋ฆ์ด ์๋๋ผ "์ด ์นธ์๋ ์ด๋ค ์ข
๋ฅ์ ๋ฐ์ดํฐ๊ฐ, ์ด๋ค ์ ์ฝ ์กฐ๊ฑด์ผ๋ก ๋ค์ด๊ฐ๋๊ฐ"๊น์ง ์ ์ํฉ๋๋ค. CharField(max_length=200)์ด๋ผ๊ณ ์ฐ๋ฉด "๋ฌธ์์ด์ธ๋ฐ 200์๊น์ง๋ง ํ์ฉํด"๋ผ๋ ๊ท์น๊น์ง ํฌํจ๋ ๊ฑฐ์ฃ .
๊ทธ๋์ makemigrations โ migrate๋ฅผ ์คํํ๋ฉด, ์ด ์ค๊ณ๋๋๋ก ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ
์ด๋ธ์ด ์์ฑ๋ฉ๋๋ค.
์ฌ๊ธฐ๊น์ง๊ฐ "๋ฐฑ์๋(์ ์ฅ์) ์ชฝ" ์ด์ผ๊ธฐ์ ๋๋ค. ๊ทธ๋ฐ๋ฐ ๋ฌธ์ ๊ฐ ํ๋ ์์ด์.
์ฌ์ฉ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ง์ ๋ชป ๊ฑด๋๋ฆฝ๋๋ค.
์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅํ๋ ค๋ฉด, ์ค๊ฐ ๋ค๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. ๊ทธ๊ฒ ๋ฐ๋ก Form์ด์์.
Form์ "์ ์ฃผ์ ์ฒญ์"์ ๋๋ค. ์ค๊ณ๋(Model)์๋ ์นธ์ด 10๊ฐ์ผ ์ ์์ง๋ง, ์ ์ฃผ์ ์ฒญ์(Form)์๋ ์ฌ์ฉ์๊ฐ ์ง์ ์ธ ์นธ๋ง ๊ณจ๋ผ์ ๋ณด์ฌ์ค๋๋ค.
class StudyForm(forms.ModelForm):
class Meta:
model = Study # ์ด๋ค ์ค๊ณ๋(๋ชจ๋ธ)์ ์ฐ๊ฒฐํ ์ง
fields = ['title', 'content'] # ๊ทธ ์ค ์ด๋ค ์นธ๋ง ๋ณด์ฌ์ค์ง
created_at์ auto_now_add=True๋ผ์ ์๋ ์
๋ ฅ๋๋๊น ์ฌ์ฉ์์๊ฒ ์ ๋ณด์ฌ์ฃผ๋ ๊ฑฐ์ฃ . ์ด๊ฒ fields์์ ๊ณจ๋ผ๋ด๋ ํ์์
๋๋ค.
์ฌ์ฉ์(๋ธ๋ผ์ฐ์ ) Django ์๋ฒ ๋ฐ์ดํฐ๋ฒ ์ด์ค
โ โ โ
โ โ ํ์ด์ง ์์ฒญ โ โ
โ โโโโโโโโโโโโโโโโโโโถ โ โ
โ View๊ฐ Form์ ๋ง๋ค์ด์ โ
โ โก ๋น ํผ ๋ณด์ฌ์ค โ โ
โ โโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ
โ โข ํผ ์์ฑ ํ ์ ์ถ โ โ
โ โโโโโโโโโโโโโโโโโโโถ โ โ
โ View๊ฐ Form์ผ๋ก โ
โ ๋ฐ์ดํฐ ๊ฒ์ฆ(validation) โ
โ โ โ
โ โฃ ๊ฒ์ฆ ํต๊ณผํ๋ฉด โ
โ form.save() ํธ์ถ โ
โ โ โโโโโโโโโโโโโโโโโโโถ โ
โ โ Model ๊ตฌ์กฐ๋๋ก โ
โ โ DB์ ์ ์ฅ โ
โ โค ์๋ฃ ์๋ต โ โ
โ โโโโโโโโโโโโโโโโโโโ โ โ
๊ฐ ๋จ๊ณ์์ ๋๊ฐ ๋ฌด์จ ์ญํ ์ธ์ง ์ ๋ฆฌํ๋ฉด ์ด๋ ์ต๋๋ค:
Model โ ๋ฐ์ดํฐ์ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๊ณ , DB์ ์ง์ ๋ํํ๋ ๊ณ์ธต
Field โ ๊ทธ ๊ตฌ์กฐ ์์ ์นธ ํ๋. ํ์
๊ณผ ๊ท์น์ ๊ฐ์ง
Form โ ์ฌ์ฉ์ ์
๋ ฅ์ ๋ฐ๊ณ , ๊ทธ ์
๋ ฅ์ด ์ฌ๋ฐ๋ฅธ์ง ๊ฒ์ฆํ๋ ๊ณ์ธต
Form์ fields โ Model์ ํ๋ ์ค ์ฌ์ฉ์์๊ฒ ๋
ธ์ถํ ๊ฒ๋ง ๊ณ ๋ฅธ ๊ฒ
View โ ์ด ๋ชจ๋ ๊ฑธ ์ฐ๊ฒฐํ๋ ๊ตํต์ ๋ฆฌ ๋ด๋น (์์ฒญ ๋ฐ๊ณ โ ํผ ์ฃผ๊ณ โ ๊ฒ์ฆํ๊ณ โ ์ ์ฅํ๊ณ โ ์๋ต)
ํต์ฌ์ ์ด๊ฒ๋๋ค: Model์ "๋ฐ์ดํฐ๊ฐ ์ด๋ป๊ฒ ์๊ฒผ๋๊ฐ"๋ฅผ ์ ์ํ๊ณ , Form์ "์ฌ์ฉ์๊ฐ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๋ฃ๋๊ฐ"๋ฅผ ์ ์ํฉ๋๋ค. ๋์ ์๋ก ๋ค๋ฅธ ๊ณ์ธต์ธ๋ฐ, ModelForm์ด ์ด ๋์ ์๋์ผ๋ก ์ฐ๊ฒฐํด์ฃผ๋ ํธ์ ์ฅ์น์ธ ๊ฑฐ์์. ModelForm ์์ด๋ Django๋ ๋์ํ์ง๋ง, ์์ผ๋ฉด Model์ ๊ตฌ์กฐ๋ฅผ Form์ด ๊ทธ๋๋ก ๊ฐ์ ธ๋ค ์ธ ์ ์์ด์ ์ฝ๋๊ฐ ํจ์ฌ ์งง์์ง๋๋ค.
๋ค์์ ๋ฆฌ
ํท๊ฐ๋ฆฌ๋ ๋จ์ด ์ฒดํฌ
ํจ์ํ view ๊ธฐ์ค์ CRUD?
CRUD ? ์์ฑ, ์์ธ , ์์ , ์ญ์ ๊ฐ๊ฐ ์ด๋ป๊ฒ ๊ตฌํ๋๋์ง ์ฒด๋?
ํจ์ํ? ํด๋์? ์ ๋๋ฆญ?
๋ธ๋ผ์ฐ์ ์ค์ฌ ํ ์ดํฐํ๋ฆ์ดํด.. ๋ธ๋ผ์ฐ์ ?
HTML ํผ ์ ๋ ฅ
POST ๋? ๊ทธ ๋ฐ๋๋ง? ๊ทธ์ธ ์ข ๋ฅ๋ ๋ฌด์์ด ์๋์ง
๊ฒ์ฆ?
์ ์ฅ
redirect ํ๋ฆ ์ดํด? ๋ป? ๊ทธ๋ฐ๋์๋ฏธ๋๋ ๊ทธ์ธ ์ข ๋ฅ ?

-์ด ํ๋ฆ์ด ์ดํด๋์ด์ผ ๋ค์ ๊ต์์์ ํด๋์คํ View, ์ ๋๋ฆญ View, DRF๊น์ง ์์ฐ์ค๋ฝ๊ฒ ์ฐ๊ฒฐ๋ฉ๋๋ค. --> ์??/
-DRF ๋ ๋ฌด์์ธ๊ฐ.
ํจ์ ํด๋์ค ์ ๋๋ฆญ ์ข ๋ฅ๋ VIEW ๋ฐ์ ์๋ ?
27๋ฒ. ๋ง์ง๋ง ๋ถ๋ถ 2์ฐจ ๊ต์์์ ํต์ฌ ํ๋ฆ

-๋ชจ๋ธํผ์์ฑ
-๋ธ๋ผ์ฐ์ ๊ธฐ๋ฐ CRUD?
-C์์ฑ D์์ธ U์์ D์ญ์ Pํ์ด์ง๋ค์ด์
--> ์ด๋ถ๋ถ์ด ? CRUD ๋ผ๋๊ฑด๊ฐ?
-๊ทธ๋ฆฌ๊ณ ์์ฑ / ์์ ํ๋ฆ์ ํนํ ์๋ ํจํด์ ๊ผญ ๊ธฐ์ตํด์ผ ํฉ๋๋ค.
-GET ์์ฒญ์ด๋? ์๋ฏธ์ ์ญํ ๊ทธ์ธ ์ข
๋ฅ
- ๋น ํผ ๋๋ ๊ธฐ์กด ๊ฐ์ด ์ฑ์์ง ํผ ๋ณด์ฌ์ฃผ๊ธฐ
-POST ์์ฒญ์ด๋? ์๋ฏธ์ ์ญํ ๊ทธ์ธ ์ข
๋ฅ
-์ฌ์ฉ์๊ฐ ์ ์ถํ ๊ฐ ๋ฐ๊ธฐ ๋ญ๋ก ๋ฐ๋์ง
-form.is_valid() ๊ฒ์ฆ ์ธ์ ์ฐ์ด๋์ง
-form.save() ์ ์ฅ ์๋ฏธ? ์ธ์ ์ฐ์ด๋์ง
-redirect() ์ด๋ ์ญํ ๊ณผ ์๋ฏธ ๊ทธ์ธ์ข
๋ฅ
-์ด ํจํด์ Django์์ ์ ๋ง ์์ฃผ ๋ฐ๋ณต๋ฉ๋๋ค. -- > ํต์ฌ?
-28. ํจ์ํ View ๊ธฐ์ค CRUD ์ ๋ฆฌ?

-ํจ์ํ View๋?
-ํจ์ํ View ๊ธฐ์ค์ผ๋ก CRUD ์ ์ฒด ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ ๊ฒ์ด ํต์ฌ์ด
-๋ค์์ ํด๋์ค view ์ ์ ๋๋ฆญ view ๋์ด๊ฐ๋. ๋ฌด์์ด ๋ค๋ฅธ๊ฐ?
-ํ์ฌ 2ํธ์์ ๋ง๋ ํจ์ํ view ์ข
๋ฅ? ์ด 5๊ฐ
-์ฆ Django CRUD์ ๊ฐ์ฅ ๊ธฐ๋ณธ ํํ๋ฅผ ํจ์ํ์ผ๋ก ๋จผ์ ์ฒด๋ํ ๊ฒ--> ์ฅ๊ณ crud ๊ธฐ๋ณธํํ๋ฅผ ํจ์ํ์ผ๋ก ๋จผ์ ์ฒด๋ --> ๋ฌด์จ์๋ฏธ


-1์ฐจ์ 2์ฐจ์ ๋ค๋ฅธ์ ์ฆ ํ๋ก์ ฏํธํ์ผ ์ฅ๊ณ ํ์ผ ์ด๋๋ฏผ์ค์น ๊ทธ์์ ์ฑํ์ฑ ์์ํ ์คํธํ๊ธฐ์ํด ์ด๋๋ฏผ์ผ๋ก ๋จผ์ ์์ ํ ์คํธํ๊ณ ์์ํ ์คํธ ์ฑ๊ณตํ๋ฉด 1์ฐจ์์ ํ๋ฆ ์ดํด๋๋ฅผ ์ํด ์ฑ ์ฌ๋ฌ๊ฐ๊ฐ ์๋ ์ฑ ํ๋๋ง ๋ง๋ค์ด์ ๊ทธ์์ study models.py ์ ํจ์๋ทฐ๋ก ๋ง๋ค๊ธฐ?
-2์ฐจ์์๋ ๋ชจ๋ธํ์ผ์ ํจ์๋ทฐ๋ก ํ๋๊ฒ ์๋ ์ฅ๊ณ ๋ด์ฅํจ์์ ๋ชจ๋ธํผ์ ์ด์ฉํ์ฌ
-C์์ฑ D์์ธ U์์ D์ญ์ Pํ์ด์ง๋ค์ด์
๋ธ๋ผ์ฐ์ ์ค์ฌ CRUD ํ
์คํธ
-๋ธ๋ผ์ฐ์ ์ค์ฌ CRUD ํ
์คํธ์ด๋ ๋ฌด์์ธ๊ฐ ?
-์ฆ ์ฅ๊ณ ๋ก ๋ฐ์ดํ ๋ฅผ ๋ณด์ฌ์ค์๋ ๋ง๋ค์๋ ์์ ํ ์๋ ์ญ์ ํ ์๋์๋ ๊ธฐ๋ณธ์ ์ธ์น์๋น์ค๋ฅผ ์์ฑ ์ํจ๊ฒ.
-์ฌ๊ธฐ์์ ์ค์ํ๊ฒ์
-GET ํผ ๋ณด์ฌ์ฃผ๊ธฐ
-POST ๊ฒ์ฆ ์ ์ฅ redirect
--> ์ดํจํด์ด Django Form ์ฒ๋ฆฌ์ ํต์ฌ! ๋ชจ๋ฅด๊ฒ ์...
ํด๋์คํ View
-โ ์ ๋๋ฆญ View
-โ DRF Serializer
-โ ViewSet
-โ Router
-โ API ํ
์คํธ