헷갈리는 단어 체크
함수형 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 처리의 핵심! 모르겠음...

Study 모델 정의
→ ModelForm 작성
→ 폼에서 입력값 검증
→ form.save()로 모델 저장
스터디 모델을 1편에서 만들었잖아요?
그 모델이랑 연결되는 form을 만들라는거에용
모델과 연관성있는 것 무언가 입력을 받는 구조의 폼이라고 생각
Form은
그냥 입력창을 만드는 도구
어떤 값을 받을지 직접 다 적어줘야 함
저장도 직접 해야 함
즉, “입력만 받는 일반 양식”이라고 이해하시면 됩니다.
ModelForm은
모델을 기준으로 폼을 쉽게 만드는 도구
모델 필드를 바탕으로 입력창을 만들 수 있음
검증도 도와주고, form.save()로 DB 저장도 쉬움
즉, “모델이랑 연결된 폼”이라고 이해하시면 됩니다.
우리가 템플릿에서 보는
태그는사용자가 입력한 값이 서버로 전달되면,
서버에서 ModelForm이 그 값을 받아 검증하고,
문제가 없으면 저장한다고 생각하시면 됩니당
study 앱에 폼을 만들고 그 폼이라는것은 그냥 앱 생성할때마다 만드는 폼이라고 생각하면되나요.. 그리고 그안에 CRUS페이지까지 스터디앱에 만드는거죠?
폼은 앱 만들 때 무조건 만드는 게 아니라, 사용자의 입력을 받아야 할 때 만드는 거예요! 항상 만드는건 아니에용 그리고 Study 앱을 만들었으니까, Study 관련 CRUD 페이지도 그 앱 안에서 같이 만듭니다
아니요, 둘 다 모델 파일과 독립적으로 사용할 수 있습니다.
forms.Form — 모델과 무관class ContactForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
forms.ModelForm — 모델과 연결됨class StudyForm(forms.ModelForm):
class Meta:
model = Study # ← 특정 모델에 종속
fields = [...]
Meta.model에 연결할 모델이 필요form.save()로 DB에 바로 저장 가능| 구분 | 모델 필요 여부 | DB 저장 |
|---|---|---|
forms.Form | ❌ 불필요 | 직접 처리해야 함 |
forms.ModelForm | ✅ 필수 | form.save()로 자동 |
즉, ModelForm만 모델 파일에 해당되고, Form은 모델 없이 어디서든 독립적으로 사용할 수 있습니다.
forms.Form이 필요한 때모델에 저장할 필요 없이 입력값만 처리할 때 사용합니다.
# 예시 1 - 검색 폼
class SearchForm(forms.Form):
keyword = forms.CharField()
# 검색어를 받아서 필터링만 할 뿐, DB에 저장 안 함
# 예시 2 - 로그인 폼
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
# 인증만 하고 저장 X
# 예시 3 - 문의/이메일 폼
class ContactForm(forms.Form):
email = forms.EmailField()
message = forms.CharField()
# 이메일로 전송만 하고 저장 X
정확히는 구분해서 불러야 합니다.
| 용어 | 설명 | 예시 |
|---|---|---|
| 클래스(Class) | 설계도 전체 | StudyForm, LoginForm |
| 메서드(Method) | 클래스 안의 함수 | clean_minutes(), save() |
| 필드(Field) | 클래스 안의 변수/속성 | title, email |
class StudyForm(forms.ModelForm): # ← 클래스
title = forms.CharField() # ← 필드
def clean_minutes(self): # ← 메서드
...
그래서
StudyForm 자체 → 클래스clean_minutes() → 메서드forms.Form, forms.ModelForm → 클래스를 상속받는 것"Form이랑 ModelForm 메서드야?" 라고 하면 엄밀히는 클래스라고 표현하는 게 맞습니다.
함수형 View (FBV, Function-Based View)
Django에서 뷰를 **함수로 작성**하는 방식이에요.
```python
# views.py
from django.shortcuts import render
def study_list(request):
studies = Study.objects.all()
return render(request, 'study/list.html', {'studies': studies})
CBV (Class-Based View) 와 비교
# ❌ 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 | |
|---|---|---|
| 구조 | 함수 | 클래스 |
| 난이도 | 쉬움 | 어려움 |
| 코드량 | 많음 | 적음 |
| 유연성 | 높음 | 낮음 |
Django 뷰의 종류: 함수뷰 vs 클래스뷰 vs 제너릭뷰
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 vs CBV vs 제너릭뷰 — CRUD 흐름 비교
CREATE (생성)
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 생성, 유효성 검사, 저장, 리다이렉트 → 모두 자동
READ (조회)
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 자동 처리
UPDATE (수정)
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/'
# 기존 데이터 자동 바인딩, 유효성 검사, 저장 모두 자동
DELETE (삭제)
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 CRUD 각 기능 역할
1. ModelForm 만들기
```python
# 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 완성입니다!
-클로드 질문
crud django 내장 함수 로 form함수가 아닌 modelform 함수를 이용하여 간단하게 만들수있는데 그때 생성 데테일 수정 삭제 기능을 만들수있는데 이 파일의 역할들은 무조건 장고 drf는 crud 기반형태로 만드는게 정석인지 궁금해 추가적으로 페이지네이션과 그외 기능들은 그것도 crud 기반인지? 결국 함수를 알아야하고 클래스를 알아야하고 장고기초를 알아야 전체적인 그림을 볼수있는거니? 각각 파일마다 형식이있는데 템플릿외에는 거의 비슷한 비슷한 구조인지 궁금해
Django DRF 구조와 CRUD 기반 설계 원리를 종합적으로 검토
Django / DRF 전체 그림 정리
1. CRUD가 정석인가?
**YES — 거의 모든 웹 개발의 기반은 CRUD입니다.**
C → Create (생성)
R → Read (조회/목록/상세)
U → Update (수정)
D → Delete (삭제)
Django든 DRF든 Spring이든 **어떤 프레임워크도 결국 CRUD를 어떻게 편하게 짜느냐**의 싸움입니다.
2. ModelForm vs DRF Serializer 비교
둘 다 같은 역할, 다른 환경
| | **ModelForm** | **DRF Serializer** |
|--|--|--|
| 용도 | HTML 템플릿 렌더링 | JSON API 응답 |
| 결과물 | 웹 페이지 | JSON 데이터 |
| 사용처 | 일반 Django | DRF (REST API) |
| 역할 | 모델 ↔ HTML Form | 모델 ↔ JSON |
> **구조는 똑같습니다.** ModelForm → Serializer로 이름만 바뀐 느낌
3. 파일별 역할 구조
myapp/
├── models.py # DB 테이블 정의 (데이터 구조)
├── serializers.py # 데이터 변환 (모델 ↔ JSON)
├── views.py # 비즈니스 로직 (CRUD 처리)
├── urls.py # URL 라우팅 (어떤 URL → 어떤 뷰)
├── admin.py # 관리자 페이지 등록
└── templates/ # HTML (DRF에선 거의 안 씀)
**템플릿 빼고는 구조가 거의 동일합니다** — 맞게 보셨어요 ✅
4. 페이지네이션도 CRUD 기반인가?
**YES — R(Read/조회)의 확장입니다.**
기본 조회 → 전체 데이터 반환
페이지네이션 → 조회 + 잘라서 반환
검색/필터 → 조회 + 조건 추가
정렬 → 조회 + 순서 지정
> 페이지네이션, 검색, 필터, 정렬 전부 **Read의 옵션**이에요
DRF에서는 설정 몇 줄로 자동 적용됩니다:
```python
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
Django/DRF는 두 가지 방식 모두 지원:
# 함수형 (FBV) - 직관적, 초보자 친화적
@api_view(['GET', 'POST'])
def post_list(request):
if request.method == 'GET':
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response(serializer.data)
# 클래스형 (CBV) - 간결, 재사용성 높음
class PostListView(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
클래스형이 더 적은 코드로 CRUD 전체를 커버합니다:
# 이 한 클래스가 List + Create를 자동으로 처리
class PostListView(generics.ListCreateAPIView): ...
# 이 한 클래스가 Detail + Update + Delete를 자동으로 처리
class PostDetailView(generics.RetrieveUpdateDestroyAPIView): ...
요청(Request)
↓
urls.py → "이 URL은 이 뷰로 보내"
↓
views.py → "CRUD 중 어떤 작업인지 판단"
↓
serializers.py → "데이터 유효성 검사 + 변환"
↓
models.py → "DB에서 읽기/쓰기"
↓
응답(Response) → JSON 반환
Python 기초 (함수, 클래스)
↓
Django 기초 (MTV 구조, ORM)
↓
CRUD 완성 (ModelForm 또는 Serializer)
↓
DRF (API 형태로 전환)
↓
심화 (페이지네이션, 인증, 필터, 권한)
> **맞습니다 — 함수 → 클래스 → Django 기초를 알아야 전체 그림이 보입니다.**
> 각 파일은 역할만 다를 뿐 **비슷한 패턴이 반복**되기 때문에, 하나를 제대로 이해하면 나머지는 빠르게 익혀집니다. 💡
Django든 DRF든 Spring이든 어떤 프레임워크도 결국 CRUD를 어떻게 편하게 짜느냐의 싸움이라고 했는데 백엔드에서 종류는?
아니요, 훨씬 더 많습니다! Django/DRF/Spring은 대표적인 예시일 뿐이고, 백엔드 프레임워크는 언어별로 굉장히 다양해요.전혀요! 저 3개는 "한국에서 많이 쓰는 것들" 중 일부일 뿐입니다.
언어별로 각자 대표 프레임워크들이 있어요:**
**Python** — Django(+DRF), FastAPI, Flask
**JVM (Java/Kotlin)** — Spring Boot, Quarkus, Ktor, Micronaut
**Node.js (JS/TS)** — Express, NestJS, Fastify, Hono
**Ruby** — Ruby on Rails (CoC 원칙으로 CRUD 속도가 가장 빠름)
**PHP** — Laravel
**Go** — Gin, Echo, Fiber
**Rust** — Actix Web, Axum
**C#** — ASP.NET Core
"CRUD 싸움"이라는 말의 핵심**은 이거예요.
아무리 기술 스택이 달라도, 99%의 웹 백엔드는 결국 이 파이프라인입니다:
> **요청 받기 → 인증/파싱 → DB 읽고/쓰고 → 응답 반환**
프레임워크마다 이걸 얼마나 *편하게*, *안전하게*, *빠르게* 만드느냐의 차이인 거죠.
한국에서 저 3개(Django, DRF, Spring)가 특히 많이 언급되는 이유**는 부트캠프 커리큘럼과 대기업(특히 Spring)의 영향이 큽니다. 실리콘밸리 스타트업에서는 Node.js + Express, 혹은 Go + Gin이 훨씬 흔해요.
https://velog.io/write?id=617a830c-7207-4d35-a346-1ebdbe9440f6

# 함수의 기본 구조
def 함수이름(입력값):
무언가 처리
return 결과값
예시
def 더하기(a, b):
result = a + b
return result
입력값 받아서 → 처리하고 → 결과 돌려주는 것
View도 똑같이 함수예요
단지 입력값이 request (요청) 이고
결과값이 response (응답) 인 것뿐
def study_list(request): ← 요청을 입력값으로 받고
처리
return response ← 응답을 결과값으로 돌려줌
사용자가 브라우저에서 주소 입력
↓
request (요청) 발생
"나 이 페이지 보고싶어!"
↓ View가 받아서 처리
response (응답) 반환
"여기 HTML 페이지 줄게!"
↓
브라우저에 화면 출력
def study_list(request): # 1. 요청 받음
studies = Study.objects.all() # 2. DB에서 데이터 꺼냄
return render( # 3. 응답 돌려줌
request,
'list.html', # 4. 이 Template을 사용해서
{'studies': studies} # 5. 이 데이터와 함께
)
단계별로 보면
1단계 사용자가 /study/ 접속
2단계 View가 요청 받음
3단계 DB에서 공부 기록 전부 꺼냄
4단계 list.html 에 데이터 넘김
5단계 완성된 HTML을 브라우저에 돌려줌
# 함수형 View
# 모든 과정이 눈에 보임
def study_list(request):
studies = Study.objects.all() ← 직접 씀
return render(request, 'list.html', {'studies': studies}) ← 직접 씀
# 클래스형 View
# 내부 과정이 숨겨져 있음
class StudyListView(ListView):
model = Study ← 이것만 써도
template_name = 'list.html' ← 위에꺼 자동으로 해줌
함수형 View
= 요청(request)을 받아서
DB 처리하고
응답(response)을 돌려주는
일반 Python 함수
특별한 게 아니라
입출력이 request/response인 그냥 함수예요 😊
전체 흐름을 쉽게 풀어드릴게요.
| 목표 | 쉽게 말하면 |
|---|---|
| Django 구조 익히기 | Django가 어떤 파일들로 이루어져 있는지 파악하기 |
| 데이터 흐름 익히기 | 모델(DB 설계) → DB 저장 → admin 확인까지의 과정 |
| 화면 출력 익히기 | DB 데이터를 꺼내서 HTML로 브라우저에 보여주기 |
"이 흐름이 이해되면 Form / CRUD / Pagination / DRF도 훨씬 덜 어렵게 느껴집니다"
이 말은 이런 뜻이에요:
이것들이 나중에 배울 더 어려운 개념들인데, 지금 배우는 "데이터 → View → Template → 브라우저" 흐름을 제대로 이해하면, 나중 개념들도 결국 이 흐름의 확장이라 훨씬 쉽게 느껴진다는 뜻입니다.
즉, 지금 이 흐름을 탄탄히 잡는 게 Django 전체의 기초라는 말이에요! 어느 부분이 특히 헷갈리세요?
예를 들어, 카카오 지도 앱을 생각해보세요.
[내 앱] ──── "서울 맛집 좌표 줘!" ───→ [카카오 서버]
[내 앱] ←─── "위도: 37.5, 경도: 126.9" ── [카카오 서버]
이렇게 서버에 데이터를 요청하고 받아오는 창구가 바로 API입니다.
데이터는 보통 JSON 형식으로 주고받아요.
| 일반 Django | DRF | |
|---|---|---|
| 응답 형식 | HTML 페이지 | JSON 데이터 |
| 사용 대상 | 브라우저 | 앱, 프론트엔드, 다른 서버 |
| 예시 | 블로그 웹사이트 | 카카오 API, 네이버 API |
일반 Django (HTML 반환)
브라우저가 /posts/ 요청
→ Django가 예쁜 HTML 페이지로 응답
DRF (JSON 반환)
앱/프론트가 /api/posts/ 요청
→ DRF가 JSON 데이터로 응답
{
"id": 1,
"title": "오늘 공부",
"time": 120
}
DB 데이터
↓
Serializer ← DRF의 핵심! (DB 데이터를 JSON으로 변환)
↓
API View ← 요청을 받아서 처리
↓
JSON 응답 ← 앱/프론트엔드로 전달
일반 Django에서 Template이 하던 역할을,
DRF에서는 Serializer가 대신한다고 보면 돼요!
일반 Django: DB → View → Template → HTML
DRF: DB → View → Serializer → JSON
구조가 거의 똑같아요! Template 자리에 Serializer가 들어간 것뿐이라,
지금 흐름을 잘 이해하면 DRF도 자연스럽게 이해되는 거예요 😊
지금 단계에서는 DRF를 바로 쓸 필요는 없고, "나중에 이런 게 있구나" 정도로만 알아두시면 충분해요! 더 궁금한 부분 있으세요?
def my_view(request):
1. 요청 처리 (GET인지 POST인지 확인)
2. DB에서 데이터 조회 (Model)
3. 비즈니스 로직 처리
4. 데이터를 Template에 넘기기
5. HTML 응답 반환
View → 1. 요청 처리
2. DB 데이터 조회
3. 비즈니스 로직 처리
4. Serializer에 데이터 넘기기
Serializer → 5. DB 데이터를 JSON으로 변환 ← 이 부분만 가져간 것
+ 들어온 JSON 데이터 유효성 검사 (보너스 역할)
View → 6. JSON 응답 반환
✅ 맞아요! Serializer는 View의 역할 중 "데이터 변환/포맷팅" 부분만 담당하는 거예요.
일반 Django로 치면 Template이 HTML로 포맷팅하던 걸,
DRF에서는 Serializer가 JSON으로 포맷팅하는 거라고 보면 정확합니다.
View는 여전히 핵심 역할을 하고, Serializer는 그 중 한 파트를 전담하는 분업 구조예요 😊
[요청 들어올 때]
클라이언트 요청
↓
View (1번째) ← 요청 받기, 어떤 데이터 꺼낼지 결정
↓
Serializer ← DB 데이터를 JSON으로 변환
↓
View (2번째) ← JSON을 응답으로 반환
↓
클라이언트에 JSON 전달
일반 Django:
클라이언트 → View(1번째) → Template → View(2번째) → 클라이언트
DRF:
클라이언트 → View(1번째) → Serializer → View(2번째) → 클라이언트
Template 자리에 Serializer가 들어간 것뿐이고,
View가 앞뒤로 두 번 역할 한다는 구조는 완전히 동일해요!
View = 교통정리 (앞에서 받고, 뒤에서 내보내고)
Serializer / Template = 중간 변환기 (데이터를 원하는 형태로 바꾸기)
이 큰 그림을 잡으셨으면 DRF 배울 때 훨씬 수월할 거예요 😊
Representational State Transfer 의 약자인데, 단어보단 개념으로 이해하는게 편해요.
"URL로 자원을 표현하고, HTTP 방식으로 행동을 표현한다"
예시로 보면
GET /api/posts/ → 게시글 목록 조회
POST /api/posts/ → 게시글 생성
GET /api/posts/1/ → 1번 게시글 조회
PUT /api/posts/1/ → 1번 게시글 수정
DELETE /api/posts/1/ → 1번 게시글 삭제
URL은 "무엇을", GET/POST/DELETE는 "어떻게" 를 나타내는 규칙이에요.
즉 REST는 API를 만들 때 지키는 설계 규칙/약속 이라고 보면 돼요.
"자주 쓰는 기능들을 미리 만들어 놓은 틀"
요리로 비유하면
Framework 없이 → 칼, 도마, 냄비 직접 다 만들어서 요리
Framework 있으면 → 주방 도구 다 갖춰진 주방에서 요리만 집중
Django 자체도 Framework예요.
로그인, DB연결, URL 라우팅 등을 직접 처음부터 안 만들어도 되게 미리 준비해둔 것이죠.
| 단어 | 의미 |
|---|---|
| REST | API 설계 규칙/약속 |
| Framework | 미리 만들어놓은 편의 도구 모음 |
| DRF | REST 규칙을 따르는 API를 쉽게 만들 수 있게 도와주는 도구 모음 |
"이 URL로 요청이 들어오면, 어느 View로 보내줄지 결정하는 것"
실생활 비유로 보면
음식점 입구 직원 = 라우터
"혼자 오셨어요?" → 1번 테이블로 안내
"2명이요" → 2번 테이블로 안내
"포장이요" → 포장 카운터로 안내
Django는 urls.py 파일에서 라우팅을 담당해요
# urls.py
urlpatterns = [
/posts/ → posts_view 함수로 보내줘
/login/ → login_view 함수로 보내줘
/admin/ → admin 페이지로 보내줘
]
사용자가 브라우저에 URL 입력
↓
/posts/ 로 요청이 들어옴
↓
urls.py 가 확인 ← 라우팅이 일어나는 곳
↓
"posts_view 로 가!"
↓
View 가 처리 시작
요청이 들어왔는데
어느 View로 보내야 할지 몰라서
그냥 멈춰버림 😵
즉 라우팅은 요청을 올바른 View로 연결해주는 교통정리 역할이에요!
Framework가 이걸 미리 만들어놨기 때문에 우리는 urls.py 에 규칙만 적어주면 되는 거예요 😊

큰 덩어리로 나눠서 설명할게요!
1. Python 설치 확인 → Django는 Python으로 돌아가니까 먼저 확인
2. 프로젝트 폴더 만들기 → 작업할 공간 생성
3. 가상환경 생성 → 이 프로젝트만의 독립된 환경 만들기
4. Django 설치 → 가상환경 안에 Django 설치
가상환경 = 프로젝트마다 별도의 방을 만드는 것
(A프로젝트 Django 3.0, B프로젝트 Django 5.0 따로 관리 가능)
5. Django 프로젝트 생성 → 집 전체 뼈대 만들기
6. 서버 실행 확인 → 뼈대가 잘 만들어졌는지 확인
7. study 앱 생성 → 집 안에 "공부방" 만들기
8. settings.py 등록 → "나 study 앱 만들었어!" 라고 Django에 알리기
프로젝트 = 집 전체
앱 = 집 안의 각 방 (공부방, 거실, 주방...)
9. templates/static 폴더 준비 → HTML파일, CSS파일 저장할 폴더 만들기
10. Study 모델 작성 → DB 설계 (어떤 데이터를 저장할지)
# 모델 예시
class Study(Model):
title <= 제목
time = 공부시간
date = 날짜
11. 마이그레이션 → 모델을 실제 DB에 반영
12. admin 등록 → admin 페이지에서 Study 모델 관리할 수 있게 등록
13. 관리자 계정 생성 → admin 페이지 로그인 계정 만들기
14. 관리자 페이지에서 데이터 확인 → DB에 데이터 잘 저장되는지 확인
15. URL 구조 설계 → 어떤 URL을 만들지 계획
16. 프로젝트 urls.py 연결 → 집 대문에서 공부방으로 길 연결
17. 앱 urls.py 연결 → 공부방 안에서 세부 길 연결
18. 임시 View로 URL 확인 → URL이 View까지 잘 연결되는지 테스트
브라우저 요청
↓
프로젝트 urls.py (대문)
↓
앱 urls.py (공부방 문)
↓
View (목적지)
19. base.html 작성 → 모든 페이지 공통 틀 만들기 (헤더, 푸터 등)
20. CSS 작성 → 페이지 꾸미기
21. 함수형 View로 목록페이지 구현 → DB 데이터 꺼내서 Template에 전달
22. 브라우저에서 최종 확인 → 완성된 페이지 확인
요청 들어옴 → View가 처리 → 응답 돌려줌
이 View를 어떤 방식으로 작성하느냐에 따라 두 가지로 나뉘어요
함수형 View (FBV)
# 함수로 작성
def study_list(request): ← 그냥 함수
studies = Study.objects.all()
return render(request, 'list.html', {'studies': studies})
클래스형 View (CBV)
# 클래스로 작성
class StudyListView(ListView): ← 클래스
model = Study
template_name = 'list.html'
함수형 View
→ 내가 처음부터 끝까지 직접 코드 작성
→ 코드가 눈에 다 보임
→ 초보자가 이해하기 쉬움
→ 자유도가 높음
클래스형 View
→ Django가 미리 만들어놓은 클래스를 가져다 씀
→ 코드가 매우 짧아짐
→ 내부 동작이 숨겨져 있음
→ 익숙해지면 생산성이 높음
함수형 View
= 요리 처음부터 끝까지 직접 하기
재료 손질 → 볶기 → 간 맞추기 → 담기
모든 과정이 내 눈에 보임
클래스형 View
= 밀키트 사용하기
Django가 이미 만들어놓은 틀에
재료(모델, 템플릿)만 넣으면 완성
내부 과정은 안 보임
똑같은 목록 페이지를 만들 때
함수형 View
def study_list(request):
studies = Study.objects.all() ← DB에서 데이터 꺼내고
return render(request, ← Template에 전달하고
'list.html',
{'studies': studies}) ← 응답 반환
클래스형 View
class StudyListView(ListView):
model = Study ← 이것만 써도
template_name = 'list.html' ← 위에꺼 전부 자동으로 해줌
클래스형은 코드가 짧지만
내부에서 무슨 일이 일어나는지 안 보이죠
함수형 View로 먼저 배우는 이유
DB에서 데이터 꺼내는 과정 ← 눈에 보임
Template에 전달하는 과정 ← 눈에 보임
응답 반환하는 과정 ← 눈에 보임
이 흐름을 직접 눈으로 보면서 익혀야
나중에 클래스형 View도 이해가 되기 때문!
함수형 View = 모든 과정을 직접 함수로 작성 (초보자용, 흐름 파악에 좋음)
클래스형 View = Django 내장 클래스 활용 (코드 짧음, 흐름이 숨겨져 있음)
함수형 먼저 익히고 → 클래스형으로 넘어가는 게 정석 순서!
환경준비 → 프로젝트/앱 생성 → 모델(DB설계) → URL연결 → 화면출력
이게 Django 프로젝트를 만드는 기본 패턴이고, 앞으로 어떤 프로젝트를 만들어도 이 순서가 반복돼요!
어느 단계가 특히 헷갈리세요? 😊




❌ 잘못된 사고 흐름
"목록 페이지 만들어야지" → "그럼 뭘 보여주지?" → "아 제목이랑 날짜?"
→ 나중에 시간도 보여주고 싶은데... 다시 설계 😵
✅ 올바른 사고 흐름
"무슨 데이터를 저장할까?" 먼저 결정
→ 그 다음 화면 설계
→ 나중에 뒤집을 일이 없음 😊
Step 1. 서비스 목적 파악
"공부시간 기록기"
→ 사용자가 공부한 내용을 기록하는 서비스
Step 2. 어떤 정보가 필요한지 나열
공부를 기록하려면 뭐가 필요할까?
- 무슨 공부를 했는지 → title
- 어떤 분야인지 → category
- 언제 했는지 → study_date
- 얼마나 했는지 → hours, minutes
- 메모할 내용 → memo
- 언제 등록했는지 → created_at (자동)
- 언제 수정했는지 → updated_at (자동)
Step 3. 각 데이터 타입 결정
title → 글자 (CharField)
category → 글자 (CharField)
study_date → 날짜 (DateField)
hours → 숫자 (IntegerField)
minutes → 숫자 (IntegerField)
memo → 긴 글자 (TextField)
created_at → 날짜+시간 (DateTimeField)
updated_at → 날짜+시간 (DateTimeField)
모델 (Study)
↓
DB 구조가 정해짐
→ title, category, hours... 컬럼 생성
↓
admin 화면이 정해짐
→ 관리자 페이지에서 저 필드들이 보임
↓
Form 구조가 정해짐
→ 입력 폼에 저 필드들이 들어감
↓
Serializer 구조가 정해짐 (DRF)
→ JSON으로 저 필드들이 나감
모델이 설계도 역할을 하기 때문에
모델만 잘 짜면 나머지는 그걸 따라가는 구조예요!
집을 지을 때
❌ 잘못된 방식
인테리어 먼저 생각
→ 나중에 방 구조 바꾸려면 벽 다 부숴야 함
✅ 올바른 방식
설계도(구조) 먼저 확정
→ 그 위에 인테리어(화면)를 올림
Django도 똑같이
❌ 화면 먼저 → 데이터 구조 나중에
✅ 데이터 구조 먼저 → 화면 나중에
"저장할 데이터가 뭔지 먼저 확정하면, DB/admin/Form/Serializer 전부 그걸 기반으로 자동으로 구조가 잡힌다"
이게 Django가 "데이터 중심 프레임워크" 라고 불리는 이유예요 😊
모델은 그냥 "이런 형태로 데이터를 저장할거야" 라고 Python으로 선언하는 것이에요
# models.py
class Study(Model): ← "Study 라는 데이터 틀을 만들겠다"
title = CharField() ← "제목이라는 칸을 만들겠다"
hours = IntegerField() ← "시간이라는 칸을 만들겠다"
memo = TextField() ← "메모라는 칸을 만들겠다"
이 자체는 그냥 설계도예요. 아직 DB에 아무것도 없음!
모델을 DB에 반영하면 엑셀 표처럼 생긴 테이블이 만들어져요
[DB에 생성되는 Study 테이블]
| id | title | hours | memo |
|----|--------------|-------|---------------|
| 1 | Django 복습 | 2 | 오늘 열심히 |
| 2 | Python 기초 | 1 | 변수 공부함 |
| 3 | 알고리즘 | 3 | BFS 어렵다 |
컬럼 = 표의 세로줄 (title, hours, memo...)
행 = 실제 저장된 데이터 1개
모델에서 선언한 필드 하나하나가
DB에서는 컬럼(세로줄) 이 되는 거예요!
admin 페이지는 DB를 눈으로 보고 직접 조작할 수 있는 화면이에요
[admin 페이지에서 데이터 추가할 때]
제목 : [ Django 복습 ] ← title 필드
시간 : [ 2 ] ← hours 필드
메모 : [ 오늘 열심히 했다 ] ← memo 필드
[저장]
모델에서 만든 필드들이
admin 페이지에서 입력칸으로 자동으로 나타나는 거예요!
나중에 일반 사용자도 데이터를 입력할 수 있게
웹 페이지에 입력 폼을 만들게 되는데
[일반 사용자가 보는 화면]
공부 기록 추가
제목 : [ Django 복습 ] ← title 필드
카테고리 : [ Python ] ← category 필드
공부시간 : [ 2 ]시간 [ 30 ]분 ← hours, minutes 필드
메모 : [ 오늘 열심히... ] ← memo 필드
[저장]
admin이랑 모양은 똑같지만
일반 사용자용 페이지에 만들어지는 입력폼이에요!
models.py에서 필드 선언
↓
DB → 컬럼(세로줄)으로 생성
admin → 입력칸으로 자동 생성
Form → 사용자용 입력칸으로 생성
모델 필드 하나를 선언하면
DB / admin / Form 에서 전부 그 필드가 나타나는 것이에요!
모델 필드 = 저장할 데이터의 칸 이름
DB 에서는 → 표의 세로줄 (컬럼)
admin 에서는 → 관리자용 입력칸
Form 에서는 → 사용자용 입력칸
이게 Django가 편한 이유예요.
모델만 잘 만들면 나머지는 자동으로 따라오거든요 😊
좋아요, 아주 기초부터 시각적으로 설명할게요!---
테이블 = 표 전체
모델 1개 → DB 테이블 1개가 만들어짐
Study 모델 → Study 테이블 생성
컬럼 (세로줄) = 모델에서 선언한 필드
title = CharField() → title 컬럼 생성
hours = IntegerField() → hours 컬럼 생성
행 (가로줄) = 실제 저장된 데이터 1건
공부 기록 1개 입력 → 표에 가로줄 1줄 추가
models.py 에서 선언
class Study:
title = CharField() → title 컬럼
hours = IntegerField() → hours 컬럼
memo = TextField() → memo 컬럼
↓ 마이그레이션 실행
DB에 Study 테이블 (빈 표) 생성
→ 데이터 저장할 때마다 행이 1줄씩 추가됨
마이그레이션 = "내가 설계한 모델을 DB에 실제로 반영해줘!" 라는 명령이에요
이제 테이블/컬럼/행 개념이 잡히셨나요? 😊
컬럼 (세로줄) = 모델에서 선언한 필드 이건 장고 내장메서드??
메서드는 아니고, Django가 미리 만들어놓은 클래스예요
CharField() → Django 내장 필드 클래스
IntegerField() → Django 내장 필드 클래스
TextField() → Django 내장 필드 클래스
DateField() → Django 내장 필드 클래스
이것들을 "Django 내장 필드 타입" 이라고 불러요
# 메서드 = 어떤 동작을 수행하는 함수
print() ← 출력하는 동작
len() ← 길이를 재는 동작
# 클래스 = 어떤 형태/틀을 정의하는 것
CharField() ← "이 칸은 글자를 저장하는 칸이야" 라고 정의
IntegerField() ← "이 칸은 숫자를 저장하는 칸이야" 라고 정의
# 그냥 이렇게만 쓰면 Django가 모름
title = ??? ← 이게 글자야? 숫자야? 날짜야?
# 필드 타입을 명시해줘야
title = CharField() ← "글자 저장하는 칸"
hours = IntegerField() ← "숫자 저장하는 칸"
DB에 테이블을 만들 때 각 컬럼이 어떤 종류의 데이터를 저장할지 알아야 하기 때문이에요!
CharField() → 짧은 글자 (제목, 이름 등)
TextField() → 긴 글자 (본문, 메모 등)
IntegerField() → 정수 숫자 (시간, 나이 등)
DateField() → 날짜 (2026-03-20)
DateTimeField() → 날짜+시간 (2026-03-20 14:30)
BooleanField() → 참/거짓 (완료여부 등)
이 모든 것들이 Django가 미리 만들어놓은 내장 필드 클래스예요.
우리는 그냥 가져다 쓰기만 하면 돼요 😊
형태를 정의하는 건 클래스라고 생각하고 어떤동작을 수행하는 함수는 메서드라고 생각하면 되겠네? 장고 내장함수기반의 ?
클래스 = 형태/틀을 정의하는 것 ← 맞아요
메서드 = 동작을 수행하는 것 ← 맞아요
메서드는 독립적으로 존재하는 게 아니라 클래스 안에 있는 함수예요
class Study: ← 클래스
title = CharField() ← 필드 (형태 정의)
def save(): ← 메서드 (클래스 안에 있는 함수)
def delete(): ← 메서드
함수 = 독립적으로 존재 → def my_func():
메서드 = 클래스 안에 존재 → class 안의 def
Django 내장 클래스 기반의 필드 타입
"함수기반" 보다는 "클래스 기반" 이 더 정확해요!
CharField, IntegerField 전부 Django가 만들어놓은 클래스니까요 😊
클래스 → 틀/형태 정의
메서드 → 클래스 안에 있는 동작 함수
필드타입 → Django 내장 클래스
이 구조가 앞으로 Django 코드 읽을 때 계속 나오니까 잘 잡아두셨어요 👍

핵심은 앞 단계가 없으면 다음 단계가 불가능하다는 거예요.
모델 (설계도)
↓ 모델이 있어야
DB 테이블 (실제 저장공간)
↓ 테이블이 있어야
admin에서 데이터 입력 가능
↓ 데이터가 있어야
목록 페이지에서 보여줄 게 생김
↓ URL이 연결되어야
View가 동작함
↓ View가 있어야
Template에 데이터를 넘길 수 있음
딱 한 단계만 빠져도 다음이 무너지는 구조예요
1. 설계도 그리기 ← 모델 작성
↓ 설계도 없이 집을 못 지음
2. 뼈대/기초 공사 ← DB 테이블 생성 (마이그레이션)
↓ 뼈대 없이 내부 공사 못함
3. 내부 확인 (임시) ← admin에서 데이터 넣어보기
↓ 데이터 없이 화면에 보여줄 게 없음
4. 인테리어 ← View + Template으로 화면 구성
모델 없이 admin 열면?
→ 보여줄 테이블 자체가 없음
데이터 없이 목록 페이지 만들면?
→ 빈 화면만 나옴
→ 내가 잘 만든건지 틀린건지 확인 불가
URL 연결 없이 View 만들면?
→ View가 있어도 접근할 방법이 없음
이 순서는 단순히 보기 좋은 순서가 아니라
앞 단계가 반드시 있어야 다음 단계가 가능한
기술적 의존 관계 순서예요!
이 순서 자체가 나중에 새 프로젝트 만들 때마다 반복하는 패턴이 돼요 😊
Admin = Django가 기본으로 제공하는
데이터 관리용 도구 (관리자 페이지)
지금 상황
→ 아직 사용자가 데이터 입력하는 화면(Form)을 안 만들었음
→ 그런데 목록 페이지를 테스트하려면 데이터가 필요함
그래서 Admin을 임시로 사용
→ "일단 여기서 데이터 넣어놓고 테스트하자!"
Admin이 필수라서가 아니라
지금 단계에서 데이터 넣을 방법이 Admin뿐이라서 쓰는 거예요
일반 사용자 → Form 페이지에서 데이터 입력
관리자 → Admin 페이지에서 데이터 관리
즉 Admin은 관리자 전용 도구일 뿐
필수 기능이 아님!
지금 교안에서 Admin 쓰는 이유
= Form이 아직 없으니까 임시로 데이터 넣는 용도
나중에 Form 만들면
= 일반 사용자는 Form으로 입력
= Admin은 있어도 되고 없어도 됨
나중에 배울 CRUD / Form 단계가 되면
Admin 없이도 데이터를 다룰 수 있게 돼요 😊
https://velog.io/write?id=3cabab5e-cf73-4ac1-a48b-aa26fc1ada39
Django → 웹 페이지(HTML) 를 만드는 프레임워크
Django DRF → 데이터(JSON) 를 주고받는 프레임워크
브라우저 요청
↓
urls.py (URL 매칭)
↓
views.py (로직 처리)
↓
models.py (DB 조회)
↓
template (HTML 생성)
↓
HTML 페이지 응답
# views.py
def todo_list(request):
todos = Todo.objects.all()
return render( # HTML 반환!
request,
"todo/todo.html", # 템플릿 파일
{"todos": todos}
)
<!-- todo.html -->
{% for todo in todos %}
<p>{{ todo.name }}</p>
{% endfor %}
결과
────────────────────────
브라우저에 HTML 페이지가 보임
화면 + 데이터 같이 반환
브라우저/앱 요청
↓
urls.py (URL 매칭)
↓
views.py (로직 처리)
↓
models.py (DB 조회)
↓
serializers.py (JSON 변환)
↓
JSON 데이터 응답
# serializers.py (DRF에만 있음!)
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = "__all__"
# views.py
class TodoViewSet(ModelViewSet):
queryset = Todo.objects.all()
serializer_class = TodoSerializer # JSON 변환!
// 결과 - JSON 데이터 반환
{
"id": 1,
"name": "공부하기",
"complete": false,
"created_at": "2026-03-06"
}
Django Django DRF
──────────────────────────────────────────
HTML 반환 JSON 반환
render() Response()
템플릿 필요 템플릿 불필요
Serializer 없음 Serializer 필수
브라우저만 사용 앱/웹 모두 사용
Django Django DRF
──────────────────────────────────────────
models.py ✅ models.py ✅
views.py ✅ views.py ✅
urls.py ✅ urls.py ✅
templates/ ✅ templates/ ❌ 불필요
serializers.py ❌ 없음 serializers.py ✅ 추가됨
# Django - 함수형 뷰
def todo_list(request):
todos = Todo.objects.all()
return render(request, # HTML 반환
"todo/todo.html",
{"todos": todos})
# DRF - 클래스형 뷰
class TodoViewSet(ModelViewSet):
queryset = Todo.objects.all()
serializer_class = TodoSerializer
# CRUD 자동 생성!
# JSON 자동 반환!
# Django urls.py
urlpatterns = [
path("todo/", views.todo_list), # 직접 연결
path("todo/<int:pk>/", views.todo_detail),
]
# DRF urls.py
router = DefaultRouter()
router.register("todo", TodoViewSet) # 자동 생성!
urlpatterns = [
path("", include(router.urls)),
]
# 자동으로 이런 URL들이 생성됨
# GET /todo/ 목록 조회
# POST /todo/ 생성
# GET /todo/1/ 상세 조회
# PUT /todo/1/ 수정
# DELETE /todo/1/ 삭제
DRF에만 있는 핵심 개념!
DB 데이터 JSON
────────────────────────────────
<Todo: 공부하기> → {"name": "공부하기"}
(Python 객체) (JSON 데이터)
역할
────────────────────────
① 데이터 변환 (Python ↔ JSON)
② 데이터 유효성 검사
③ 데이터 저장
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo # 어떤 모델?
fields = "__all__" # 어떤 필드?
Django 사용 DRF 사용
──────────────────────────────────────
웹사이트만 만들 때 앱도 같이 만들 때
HTML 페이지 필요할 때 API 서버 만들 때
혼자 쓰는 서비스 여러 플랫폼 서비스
블로그, 쇼핑몰 카카오, 인스타그램
Django
──────────────────────────────────────
요청 → URL → View → Model → Template → HTML
DRF
──────────────────────────────────────
요청 → URL → View → Model → Serializer → JSON
차이점
Template → Serializer 로 바뀐 것!
HTML → JSON 으로 바뀐 것!
Django
────────────────────────
HTML 만드는 도구
눈에 보이는 화면 제공
템플릿(HTML) 이 핵심
DRF
────────────────────────
데이터 주고받는 도구
JSON 데이터 제공
Serializer 가 핵심
결론
────────────────────────
Django = 완성된 음식 제공 🍱
DRF = 재료(데이터)만 제공 🥩
(요리는 앱/프론트가 함)
https://velog.io/write?id=f38a7a87-f649-477d-922b-d65bf9720f0b
모델 데이터가 중요 --> URL --> VIEW --> TRMPLETE
VIEW는 많은역할을 함 그래서 1편에서 2편으로 넘어갈때 코드가 동일한지 확인체크
ModelForm을 만들고, 함수형 View 기준으로 공부기록 생성(Create), 상세(Detail), 수정(Update), 삭제(Delete), 페이지네이션까지 완성하며 브라우저 기반 CRUD 흐름을 자세히 익힙니다.



# 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']

| GET | POST | |
|---|---|---|
| 용도 | 데이터 조회 | 데이터 전송/저장 |
| 데이터 위치 | URL에 노출 | Body에 숨겨짐 |
| 보안 | 낮음 | 높음 |
| 데이터 크기 | 제한 있음 | 제한 없음 |
| 캐싱 | 가능 | 불가능 |
# GET - URL에 데이터가 보임
https://example.com/search?keyword=python&page=1
# POST - URL에 데이터가 안 보임
https://example.com/login
(아이디/비밀번호는 숨겨져서 전송)
def my_view(request):
# GET 요청 - 데이터 조회할 때
if request.method == 'GET':
posts = Post.objects.all()
return render(request, 'list.html', {'posts': posts})
# POST 요청 - 데이터 저장할 때
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.save() # DB 저장
질문 GET POST
GET → 검색, 목록 조회, 상세 보기
POST → 로그인, 회원가입, 게시글 작성, 수정, 삭제
HTML 폼에서
<!-- GET 방식 -->
<form method="GET">
<input type="text" name="keyword">
</form>
<!-- POST 방식 -->
<form method="POST">
{% csrf_token %} <!-- Django 보안 토큰 필수! -->
<input type="text" name="title">
</form>
💡 조회는 GET, 변경은 POST 로 기억하세요!
질문 장고에서의 모델 폼에대한 설명과 사용쓰임방법
DB 모델(Model) + HTML 폼(Form) 을 자동으로 연결해주는 Django 내장 클래스
기본 구조
# forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post # 어떤 모델을 사용할지
fields = ['title', 'content'] # 어떤 필드를 폼에 보여줄지
# fields = '__all__' # 모든 필드 사용할 때
Model 예시
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100) # 제목
content = models.TextField() # 내용
created_at = models.DateTimeField(auto_now_add=True) # 생성일
CRUD별 사용 방법
✅ 생성 (Create)
# views.py
def post_create(request):
if request.method == 'POST':
form = PostForm(request.POST) # 입력된 데이터 받기
if form.is_valid(): # 유효성 검사
form.save() # DB 저장
return redirect('post_list')
else:
form = PostForm() # 빈 폼 생성
return render(request, 'create.html', {'form': form})
✅ 수정 (Update)
# views.py
def post_update(request, pk):
post = Post.objects.get(pk=pk)
if request.method == 'POST':
form = PostForm(request.POST, instance=post) # 기존 데이터 불러오기
if form.is_valid():
form.save() # 수정된 내용 저장
return redirect('post_list')
else:
form = PostForm(instance=post) # 기존 데이터로 폼 채우기
return render(request, 'update.html', {'form': form})
✅ 삭제 (Delete)
# views.py
def post_delete(request, pk):
post = Post.objects.get(pk=pk)
if request.method == 'POST':
post.delete() # DB에서 삭제
return redirect('post_list')
return render(request, 'delete.html', {'post': post})
HTML 템플릿에서 사용
<!-- create.html -->
<form method="POST">
{% csrf_token %} <!-- 보안 토큰 필수! -->
{{ form.as_p }} <!-- 폼 자동 렌더링 -->
<button type="submit">저장</button>
</form>
폼 렌더링 방식 3가지
{{ form.as_p }} <!-- <p> 태그로 감싸서 출력 -->
{{ form.as_table }} <!-- <table> 태그로 출력 -->
{{ form.as_ul }} <!-- <ul> 태그로 출력 -->
유효성 검사
form = PostForm(request.POST)
if form.is_valid(): # 유효성 통과 ✅
form.save()
else:
print(form.errors) # 어떤 오류인지 출력 ❌
fields 설정 방법
class Meta:
model = Post
fields = '__all__' # 모든 필드
fields = ['title', 'content'] # 특정 필드만 포함
exclude = ['created_at'] # 특정 필드만 제외
일반 Form vs ModelForm 비교
# ❌ 일반 Form - 직접 다 작성
class PostForm(forms.Form):
title = forms.CharField()
content = forms.CharField()
# DB 저장도 직접 작성해야 함
# ✅ ModelForm - 자동 처리
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
# DB 저장은 form.save() 한 줄!
핵심 메서드 정리
| 메서드 | 설명 |
|---|---|
form.is_valid() | 입력값 유효성 검사 |
form.save() | DB에 저장 |
form.errors | 오류 내용 확인 |
form.as_p() | p태그로 렌더링 |
instance=post | 기존 데이터 불러오기 |
💡 ModelForm = 모델 기반 자동 폼 생성 + 유효성 검사 + DB 저장 을 한번에 처리해주는 Django의 핵심 기능입니다!
질문 Django Form / ModelForm은 왜 필요하며 둘 차이점?
Django Form vs ModelForm
왜 필요한가?
HTML 폼만 사용하면 아래를 전부 직접 작성해야 함 😱
1. HTML input 태그 하나하나 작성
2. 유효성 검사 직접 작성
3. DB 저장 코드 직접 작성
4. 보안 처리 직접 작성
→ Form / ModelForm 사용하면 자동으로 해결! 😊
Django Form
# forms.py
from django import forms
class PostForm(forms.Form):
title = forms.CharField(max_length=100) # 직접 필드 정의
content = forms.CharField() # 직접 필드 정의
# views.py
def post_create(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
# ❌ DB 저장 코드를 직접 작성해야 함
Post.objects.create(
title=form.cleaned_data['title'],
content=form.cleaned_data['content']
)
else:
form = PostForm()
return render(request, 'create.html', {'form': form})
Django ModelForm
# forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post # 모델 연결
fields = '__all__' # 필드 자동 생성
# views.py
def post_create(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.save() # ✅ 한 줄로 DB 저장
else:
form = PostForm()
return render(request, 'create.html', {'form': form})
핵심 차이점
| Form | ModelForm | |
|---|---|---|
| 필드 정의 | 직접 작성 | 모델에서 자동 생성 |
| DB 저장 | 직접 작성 | form.save() 한 줄 |
| 모델 연결 | ❌ 없음 | ✅ 자동 연결 |
| 코드량 | 많음 | 적음 |
| 유효성 검사 | ✅ 가능 | ✅ 가능 |
| 사용 상황 | DB 불필요한 폼 | DB 연동 필요한 폼 |
언제 무엇을 쓰나요?
✅ Form 사용
- 로그인 (DB 저장 없이 검증만)
- 검색 폼
- 이메일 문의 폼
- DB와 관계없는 데이터 처리
✅ ModelForm 사용
- 게시글 작성/수정
- 회원가입
- 댓글 작성
- DB에 저장이 필요한 모든 것
한눈에 비교
# Form - 검색 폼 예시 (DB 저장 X)
class SearchForm(forms.Form):
keyword = forms.CharField()
# ModelForm - 게시글 폼 (DB 저장 O)
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
💡 DB 저장이 필요하면 ModelForm, 아니면 Form!
ModelForm은 Form의 기능을 모두 포함하면서 DB 연동까지 자동으로 해줍니다.
Study 모델 정의
→ ModelForm 작성
→ 폼에서 입력값 검증
→ form.save()로 모델 저장
스터디 모델을 1편에서 만들었잖아요?
그 모델이랑 연결되는 form을 만들라는거에용
모델과 연관성있는 것 무언가 입력을 받는 구조의 폼이라고 생각
Form은
그냥 입력창을 만드는 도구
어떤 값을 받을지 직접 다 적어줘야 함
저장도 직접 해야 함
즉, “입력만 받는 일반 양식”이라고 이해하시면 됩니다.
즉, “모델이랑 연결된 폼”이라고 이해하시면 됩니다.
우리가 템플릿에서 보는 태그는
사용자가 값을 입력해서 보내는 HTML 영역이에요!
사용자가 입력한 값이 서버로 전달되면,
서버에서 ModelForm이 그 값을 받아 검증하고,
문제가 없으면 저장한다고 생각하시면 됩니당
study 앱에 폼을 만들고 그 폼이라는것은 그냥 앱 생성할때마다 만드는 폼이라고 생각하면되나요.. 그리고 그안에 CRUS페이지까지 스터디앱에 만드는거죠?
폼은 앱 만들 때 무조건 만드는 게 아니라, 사용자의 입력을 받아야 할 때 만드는 거예요! 항상 만드는건 아니에용 그리고 Study 앱을 만들었으니까, Study 관련 CRUD 페이지도 그 앱 안에서 같이 만듭니다
아니요, 둘 다 모델 파일과 독립적으로 사용할 수 있습니다.
forms.Form — 모델과 무관class ContactForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
forms.ModelForm — 모델과 연결됨class StudyForm(forms.ModelForm):
class Meta:
model = Study # ← 특정 모델에 종속
fields = [...]
Meta.model에 연결할 모델이 필요form.save()로 DB에 바로 저장 가능| 구분 | 모델 필요 여부 | DB 저장 |
|---|---|---|
forms.Form | ❌ 불필요 | 직접 처리해야 함 |
forms.ModelForm | ✅ 필수 | form.save()로 자동 |
즉, ModelForm만 모델 파일에 해당되고, Form은 모델 없이 어디서든 독립적으로 사용할 수 있습니다.
forms.Form이 필요한 때모델에 저장할 필요 없이 입력값만 처리할 때 사용합니다.
# 예시 1 - 검색 폼
class SearchForm(forms.Form):
keyword = forms.CharField()
# 검색어를 받아서 필터링만 할 뿐, DB에 저장 안 함
# 예시 2 - 로그인 폼
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
# 인증만 하고 저장 X
# 예시 3 - 문의/이메일 폼
class ContactForm(forms.Form):
email = forms.EmailField()
message = forms.CharField()
# 이메일로 전송만 하고 저장 X
정확히는 구분해서 불러야 합니다.
| 용어 | 설명 | 예시 |
|---|---|---|
| 클래스(Class) | 설계도 전체 | StudyForm, LoginForm |
| 메서드(Method) | 클래스 안의 함수 | clean_minutes(), save() |
| 필드(Field) | 클래스 안의 변수/속성 | title, email |
class StudyForm(forms.ModelForm): # ← 클래스
title = forms.CharField() # ← 필드
def clean_minutes(self): # ← 메서드
...
그래서
StudyForm 자체 → 클래스clean_minutes() → 메서드forms.Form, forms.ModelForm → 클래스를 상속받는 것"Form이랑 ModelForm 메서드야?" 라고 하면 엄밀히는 클래스라고 표현하는 게 맞습니다.
이제 실제로 Study 모델과 연결되는 StudyForm을 만듭니다.
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 완성입니다!


이 순서는 기능을 그냥 나열한 것이 아닙니다.
예를 들어:
폼이 있어야 생성/수정 기능을 만들 수 있습니다.
상세 페이지가 있어야 수정/삭제 이후 이동 흐름도 자연스러워집니다.
CRUD가 어느 정도 끝나야 페이지네이션을 실제로 체감할 수 있습니다.
즉 이번 교안도 여전히 실제 실습 순서 기준으로 설계되어 있습니다.
2번 하기전 준비


path() 구조 분석
pythonpath('', views.study_list, name='list')
path(경로, 뷰함수, name=이름) — 총 3개의 인자로 구성됩니다.
form.save() 한 줄로 저장되는 이유쉽게 비유하면:
일반 Form = 그냥 빈 종이
ModelForm = Study 모델과 연결된 자동완성 종이
# ModelForm은 이미 내부에 이런 동작이 내장되어 있음
class StudyForm(forms.ModelForm):
class Meta:
model = Study # ← "나는 Study랑 연결됐어"
fields = ['title', ...] # ← "이 필드들을 저장해"
# 그래서 form.save() 한 줄이
# 내부적으로 이걸 자동으로 해줌
study = Study(
title = form.cleaned_data['title'],
category = form.cleaned_data['category'],
...
)
study.save() # DB 저장
form.save()= "연결된 모델에 알아서 넣고 저장해줘" 라는 명령
from django.shortcuts import redirect, render # ← 임포트
from .forms import StudyForm # ← 임포트
from .models import Study # ← 임포트
import = 다른 파일에서 필요한 것만 가져오는 것
from 어디서 import 무엇을def study_list(request): # ← 함수
...
return render(...)
def study_create(request): # ← 함수
...
return render(...)
def = 함수입니다 (메서드 아님)
| 구분 | 위치 | 예시 |
|---|---|---|
| 함수 | 클래스 밖에 독립적으로 존재 | def study_list(request) |
| 메서드 | 클래스 안에 존재 | def clean_minutes(self) |
def study_create(request):
form = StudyForm(request.POST or None)
if request.method == 'POST' and form.is_valid():
form.save()
return redirect('study:list') # ← if 안의 return
return render(request, 'study/study_form.html', {...}) # ← 함수의 return
return이 2개인 이유
사용자가 처음 페이지 접속 (GET 요청)
→ if 조건 False → 아래 render() 실행 → 폼 화면 보여줌
사용자가 폼 작성 후 제출 (POST 요청)
→ if 조건 True → form.save() → redirect로 목록으로 이동
# 1. 임포트 (재료 가져오기)
from django.shortcuts import redirect, render
# 2. 함수 정의 (클래스 밖 → 함수)
def study_create(request):
# 3. 변수 선언
form = StudyForm(request.POST or None)
# 4. 조건 분기
if request.method == 'POST' and form.is_valid():
form.save()
return redirect('study:list') # POST면 여기서 끝
return render(...) # GET이면 여기서 끝
핵심:
def가 클래스 밖에 있으면 → 함수, 클래스 안에 있으면 → 메서드
이제 study_create View를 추가합니다.
{% extends 'base.html' %}
base.html을 부모로 삼음{% block title %}
{{ page_title }} | 공부시간 기록기
{% endblock %}
{% block content %}
... 실제 내용 ...
{% endblock %}
block = base.html에 뚫어놓은 구멍title → 브라우저 탭 제목content → 실제 화면에 보이는 내용 전체{% block content %}
│
├── section.hero-card ← 상단 소개 영역
│ 제목, 설명글
│
└── section.content-card ← 실제 폼 영역
form
hero-card (소개 영역)
<section class="hero-card">
<span>Study Form</span> <!-- 작은 라벨 -->
<h1>{{ page_title }}</h1> <!-- 큰 제목 (views.py에서 전달) -->
<p>오늘의 공부를 구체적으로...</p> <!-- 설명글 -->
</section>
content-card (폼 영역)
<section class="content-card">
<form method="post">
{% csrf_token %} <!-- 보안 토큰 -->
공부 제목
카테고리
공부 날짜
시간 / 분 ← 이 둘은 나란히 배치 (inline-2)
메모
저장하기 버튼 / 목록으로 버튼
</form>
</section>
모든 필드가 똑같은 패턴으로 반복됩니다
<div class="form-row">
<!-- 라벨 -->
<label for="{{ form.title.id_for_label }}">
{{ form.title.label }}
</label>
<!-- 입력창 -->
{{ form.title }}
<!-- 에러 메시지 (있을 때만 표시) -->
{% if form.title.errors %}
{{ form.title.errors }}
{% endif %}
</div>
| 부분 | 역할 |
|---|---|
label | 입력창 설명 텍스트 |
{{ form.title }} | 실제 input 태그 렌더링 |
form.title.errors | 검증 실패시 에러 출력 |
① 시간/분 나란히 배치
<div class="form-row inline-2">
<div> 시간 입력 </div>
<div> 분 입력 </div>
</div>
inline-2 클래스로 두 개를 가로로 나란히 배치② 보안 토큰
<form method="post">
{% csrf_token %}
base.html 레이아웃 상속
→ 소개 영역 (hero-card)
→ 폼 영역 (content-card)
→ 필드마다 라벨 + 입력창 + 에러메시지 패턴 반복
→ 저장 or 목록으로 버튼
CSS에 폼 관련 스타일 추가하기
브라우저에서 생성 기능 먼저 확인하기
1편에서는 데이터를 admin에서만 넣고 테스트? 실제 웹페이지에서 직접 데이터 넣고 테스트?
→ 1편은 보통 admin으로 먼저 넣어보는 연습에 가깝고, 2편부터는 실제 웹페이지 폼으로 직접 입력하는 흐름
2번째 교안의 목표
→ 브라우저에서 직접 데이터 입력 → 저장 → 목록/상세/수정/삭제까지 흐름 이해
모델폼? ModModel form?
→ ModModel form은 아니고 ModelForm이 맞습니다. 혹시 어디 오타가 있었나요..?! → Django 모델과 연결된 폼을 쉽게 만드는 도구예요.
함수형 view 기준의 CRUD?
→ 네, 2편에서는 함수형 view(FBV) 기준으로 CRUD를 먼저 배웁니다.
CRUD? 생성, 상세, 수정, 삭제 각각 어떻게 구현되는지 체득? → 넵. 맞아요
함수형? 클래스? 제너릭?
→ 전부 view를 만드는 방식입니다. → 함수형 → 클래스형 → 제너릭 순서로 배웠었죠?
브라우저 중심 데이터 흐름 이해.. 브라우저?
→ 사용자가 실제로 보는 웹페이지 화면이라고 생각하면 됩니다. 즉, 사용자가 브라우저에서 입력하면 서버가 받아서 처리하는 흐름이에요.
HTML 폼 입력
→ 사용자가 브라우저 화면에서 글자를 입력하고 제출하는 입력창입니다.
POST란? 그 반대말? 그 외 종류는?
→ POST는 보통 데이터를 서버에 저장/전송할 때 씁니다.
→ 반대로 조회할 때는 보통 GET을 씁니다.
→ 그 외에 PUT, PATCH, DELETE 같은 방식도 있습니다.
검증?
→ 사용자가 입력한 값이 비어 있지 않은지, 형식이 맞는지 확인하는 과정입니다.
저장
→ 검증이 끝난 데이터를 DB에 넣는 것입니다.
redirect 흐름 이해? 뜻? 그 반대 의미 또는 그 외 종류?
→ redirect는 처리 후에 다른 페이지로 이동시키는 것입니다.
→ 예를 들면 저장 후 목록 페이지로 보내는 것.
→ 반대로는 현재 페이지를 그대로 다시 보여주는 render가 있습니다.
이 흐름이 이해되어야 다음 교안에서 클래스형 View, 제너릭 View, DRF까지 자연스럽게 연결됩니다. --> 왜?
→ 왜냐하면 나중 방식들도 결국 똑같이 요청 받기 → 검증 → 저장/조회 → 응답하기 이 흐름 위에서 동작하기 때문입니다. 겉모습만 달라지고 기본 원리는 같습니다.
DRF는 무엇인가.
→ Django REST Framework의 줄임말입니다.
→ Django로 API를 만들기 쉽게 해주는 도구예요.
함수 클래스 제너릭 종류는 VIEW밖에 없나?
→ 보통 여기서는 view의 종류를 말하는 게 맞습니다. 함수형 view, 클래스형 view, 제너릭 view는 화면/요청 처리 방식의 차이예요.