Django 기초 - 공부시간 기록기 만들기(2)_헷갈리는부분

HY_1023·2026년 4월 9일

MENTOS

목록 보기
19/19

https://www.figma.com/design/wDh3su4KrlhkzOM1d7vKBT/Django-%EA%B8%B0%EC%B4%88---%EA%B3%B5%EB%B6%80%EC%8B%9C%EA%B0%84-%EA%B8%B0%EB%A1%9D%EA%B8%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0-2-?node-id=17-98&p=f&t=huYfHj2496lbwPcI-0

헷갈리는 단어 체크

  • 1편에서는 데이터를 admin에서만 넣고 테스트 ? 실제 웹페이지에서 직접데이터 넣고 테스트?
  • 2번째 교안의 목표
    - 모델폼? ModModel 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 기본형태를 함수형으로 먼저 체득 --> 무슨의미

  • 30.체크리스트에서
    - 모델폼 형성
    -C생성 D상세 U수정 D삭제 P페이지네이션
    - url -> view -> templete 방식으로 진행이 되는거 같은데 상세템플릿을 만든 다음 목록에서 상세 페이지로 이동 할수있다..? 갑자기왜?
    • 수정에서 url view 그 다음 새로운 템플릿이 아닌 기존값이 채워진 수정 폼이 열리는 부분
    • 수정 후 상세 페이지에서 반영된 결과를 볼 수 있다. --> 코드가 분석해야한다.
    • 삭제에서 url -> view -> templete 방식 까지는 이해되지만, 그 다음이 이해가 어려움
    • 삭제 전 확인 페이지가 나온다.
      -삭제 후 목록에서 데이터가 사라진다.
      -페이지 네이션 이란?
    • 데이터 6개 이상으로 페이지 이동을 확인했다.
  1. 결론

-1차와 2차의 다른점 즉 프로젯트파일 장고 파일 어드민설치 그안에 앱형성 임시테스트하기위해 어드민으로 먼저 임시 테스트하고 임시테스트 성공하면 1차에서 흐름 이해도를 위해 앱 여러개가 아닌 앱 하나만 만들어서 그안에 study models.py 에 함수뷰로 만들기?

-2차에서는 모델파일을 함수뷰로 하는게 아닌 장고내장함수의 모델폼을 이용하여
-C생성 D상세 U수정 D삭제 P페이지네이션 브라우저 중심 CRUD 테스트
-브라우저 중심 CRUD 테스트이란 무엇인가 ?

-즉 장고로 데이토를 보여줄수도 만들수도 수정할수도 삭제할수도있는 기본적인웹서비스를 완성 시킨것.

-여기에서 중요한것은
-GET 폼 보여주기
-POST 검증 저장 redirect

--> 이패턴이 Django Form 처리의 핵심! 모르겠음...

  • 3차 교안에서는 “브라우저 기반 CRUD”를 넘어서, Django를 더 Django답게 사용하는 구조와 API 확장 흐름까지 가게 됩니다. -함수형 View 복습
    • 클래스형 View
      -→ 제너릭 View
      -→ DRF Serializer
      -→ ViewSet
      -→ Router
      -→ API 테스트

정리한것에 찾기

  • 1편에서는 데이터를 admin에서만 넣고 테스트 ? 실제 웹페이지에서 직접데이터 넣고 테스트?

  • 모델폼? ModModel form?

1편 순서기억 이해

Form / ModelForm을 쓰는 이유

나의질문 폼이랑 모델폼차이가 이해가 안되신다는건가용??

Study 모델 정의
→ ModelForm 작성
→ 폼에서 입력값 검증
→ form.save()로 모델 저장

답변

스터디 모델을 1편에서 만들었잖아요?
그 모델이랑 연결되는 form을 만들라는거에용
모델과 연관성있는 것 무언가 입력을 받는 구조의 폼이라고 생각

Form은
그냥 입력창을 만드는 도구
어떤 값을 받을지 직접 다 적어줘야 함
저장도 직접 해야 함

즉, “입력만 받는 일반 양식”이라고 이해하시면 됩니다.

ModelForm은
모델을 기준으로 폼을 쉽게 만드는 도구
모델 필드를 바탕으로 입력창을 만들 수 있음
검증도 도와주고, form.save()로 DB 저장도 쉬움

즉, “모델이랑 연결된 폼”이라고 이해하시면 됩니다.

우리가 템플릿에서 보는

태그는
사용자가 값을 입력해서 보내는 HTML 영역이에요!

사용자가 입력한 값이 서버로 전달되면,
서버에서 ModelForm이 그 값을 받아 검증하고,
문제가 없으면 저장한다고 생각하시면 됩니당

나의질문

study 앱에 폼을 만들고 그 폼이라는것은 그냥 앱 생성할때마다 만드는 폼이라고 생각하면되나요.. 그리고 그안에 CRUS페이지까지 스터디앱에 만드는거죠?

답변

폼은 앱 만들 때 무조건 만드는 게 아니라, 사용자의 입력을 받아야 할 때 만드는 거예요! 항상 만드는건 아니에용 그리고 Study 앱을 만들었으니까, Study 관련 CRUD 페이지도 그 앱 안에서 같이 만듭니다


Form vs ModelForm 적용 범위

아니요, 둘 다 모델 파일과 독립적으로 사용할 수 있습니다.


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은 모델 없이 어디서든 독립적으로 사용할 수 있습니다.


1. 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

2. "메서드"라는 표현에 대해

정확히는 구분해서 불러야 합니다.

용어설명예시
클래스(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 메서드야?" 라고 하면 엄밀히는 클래스라고 표현하는 게 맞습니다.


  1. 함수형? 클래식? 제너릭?

함수형 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'
FBVCBV
구조함수클래스
난이도쉬움어려움
코드량많음적음
유연성높음낮음

Django 뷰의 종류: 함수뷰 vs 클래스뷰 vs 제너릭뷰

  1. 함수 기반 뷰 (Function-Based View, FBV)
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})

특징

  • 가장 단순하고 직관적
  • 흐름이 명확해서 읽기 쉬움
  • HTTP 메서드 분기를 직접 처리해야 함 (if request.method == 'POST':)
  • 재사용성이 낮음
  1. 클래스 기반 뷰 (Class-Based View, CBV)
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 요청 처리
        ...

특징

  • HTTP 메서드(GET, POST 등)를 메서드로 자동 분기
  • 상속과 믹스인(Mixin)으로 코드 재사용 가능
  • 복잡한 뷰일수록 구조화하기 유리
  • FBV보다 초기 학습 곡선이 있음
  1. 제너릭 뷰 (Generic View)

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 → 로직이 복잡하거나 특수한 경우, 팀원 모두 Django에 익숙하지 않을 때
  • 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가** 처리, 나는 설정만 |
        

  • CRUD ? 생성, 상세 , 수정 , 삭제 각각 어떻게 구현되는지 체득?

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가 반복적인 폼 작업을 자동화해주기 위해 만든 강력한 내장 기능입니다!

  1. 생성 (Create)
사용자가 폼에 데이터 입력 → DB에 새 데이터 저장
예) 게시글 작성, 회원가입

새로운 데이터를 추가하는 기능

  1. 상세 (Detail)
목록에서 항목 클릭 → 해당 데이터 상세 내용 표시
예) 게시글 본문 보기

특정 데이터 하나를 자세히 조회하는 기능

  1. 수정 (Update)
기존 데이터를 불러와 폼에 표시 → 수정 후 저장
예) 게시글 편집

기존 데이터를 변경하는 기능

  1. 삭제 (Delete)
특정 데이터 선택 → DB에서 완전 삭제
예) 게시글 삭제

데이터를 DB에서 제거하는 기능

  1. 페이지네이션 (Pagination)
데이터가 많을 때 → 한 페이지에 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
}
  1. 함수형 vs 클래스형 뷰

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): ...
  1. 전체 흐름 한눈에
요청(Request)
    ↓
urls.py       → "이 URL은 이 뷰로 보내"
    ↓
views.py      → "CRUD 중 어떤 작업인지 판단"
    ↓
serializers.py → "데이터 유효성 검사 + 변환"
    ↓
models.py     → "DB에서 읽기/쓰기"
    ↓
응답(Response) → JSON 반환
  1. 결론 — 공부 순서
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/@hy_1023/Django-%EA%B8%B0%EC%B4%88-%EA%B3%B5%EB%B6%80%EC%8B%9C%EA%B0%84-%EA%B8%B0%EB%A1%9D%EA%B8%B0-%EB%A7%8C%EB%93%A4%EA%B8%B01-%EC%84%B8%EB%B2%88%EC%A7%B8-%ED%97%B7%EA%B0%88%EB%A6%AC%EB%8A%94-%EB%B6%80%EB%B6%84](https://velog.io/@hy_1023/Django-%EA%B8%B0%EC%B4%88-%EA%B3%B5%EB%B6%80%EC%8B%9C%EA%B0%84-%EA%B8%B0%EB%A1%9D%EA%B8%B0-%EB%A7%8C%EB%93%A4%EA%B8%B02)

https://velog.io/write?id=617a830c-7207-4d35-a346-1ebdbe9440f6


함수형 View 기초부터


🔤 먼저 "함수"가 뭔지부터

# 함수의 기본 구조
def 함수이름(입력값):
    무언가 처리
    return 결과값

예시

def 더하기(a, b):
    result = a + b
    return result

입력값 받아서 → 처리하고 → 결과 돌려주는 것


🔤 함수형 View는?

View도 똑같이 함수예요
단지 입력값이 request (요청) 이고
결과값이 response (응답) 인 것뿐

def study_list(request):   ← 요청을 입력값으로 받고
    처리
    return response        ← 응답을 결과값으로 돌려줌

🔄 request / response 가 뭔지

사용자가 브라우저에서 주소 입력
        ↓
request (요청) 발생
"나 이 페이지 보고싶어!"

        ↓ View가 받아서 처리

response (응답) 반환
"여기 HTML 페이지 줄게!"
        ↓
브라우저에 화면 출력

👀 실제 함수형 View 코드

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랑 비교

# 함수형 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인 그냥 함수예요 😊


이 교안 내용 설명

전체 흐름을 쉽게 풀어드릴게요.


📌 이번 교안의 목표 3가지

목표쉽게 말하면
Django 구조 익히기Django가 어떤 파일들로 이루어져 있는지 파악하기
데이터 흐름 익히기모델(DB 설계) → DB 저장 → admin 확인까지의 과정
화면 출력 익히기DB 데이터를 꺼내서 HTML로 브라우저에 보여주기

🔴 빨간 박스 부분 설명

"이 흐름이 이해되면 Form / CRUD / Pagination / DRF도 훨씬 덜 어렵게 느껴집니다"

이 말은 이런 뜻이에요:

  • Form → 사용자 입력 처리
  • CRUD → 데이터 생성/조회/수정/삭제
  • Pagination → 목록을 여러 페이지로 나누기
  • DRF → Django REST Framework (API 만들기)

이것들이 나중에 배울 더 어려운 개념들인데, 지금 배우는 "데이터 → View → Template → 브라우저" 흐름을 제대로 이해하면, 나중 개념들도 결국 이 흐름의 확장이라 훨씬 쉽게 느껴진다는 뜻입니다.

즉, 지금 이 흐름을 탄탄히 잡는 게 Django 전체의 기초라는 말이에요! 어느 부분이 특히 헷갈리세요?


Django REST Framework (DRF) 란?


🌐 먼저 "API"가 뭔지부터

예를 들어, 카카오 지도 앱을 생각해보세요.

[내 앱] ──── "서울 맛집 좌표 줘!" ───→ [카카오 서버]
[내 앱] ←─── "위도: 37.5, 경도: 126.9" ── [카카오 서버]

이렇게 서버에 데이터를 요청하고 받아오는 창구가 바로 API입니다.
데이터는 보통 JSON 형식으로 주고받아요.


🔄 일반 Django vs DRF 차이

일반 DjangoDRF
응답 형식HTML 페이지JSON 데이터
사용 대상브라우저앱, 프론트엔드, 다른 서버
예시블로그 웹사이트카카오 API, 네이버 API

📦 실제 예시로 보면

일반 Django (HTML 반환)

브라우저가 /posts/ 요청
→ Django가 예쁜 HTML 페이지로 응답

DRF (JSON 반환)

앱/프론트가 /api/posts/ 요청
→ DRF가 JSON 데이터로 응답

{
  "id": 1,
  "title": "오늘 공부",
  "time": 120
}

🏗️ DRF의 핵심 구조

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를 바로 쓸 필요는 없고, "나중에 이런 게 있구나" 정도로만 알아두시면 충분해요! 더 궁금한 부분 있으세요?


거의 맞아요! 조금만 더 정확하게 잡아드릴게요


일반 Django View가 하는 역할들

def my_view(request):
    1. 요청 처리 (GET인지 POST인지 확인)
    2. DB에서 데이터 조회 (Model)
    3. 비즈니스 로직 처리
    4. 데이터를 Template에 넘기기
    5. HTML 응답 반환

DRF에서 역할 분담

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는 그 중 한 파트를 전담하는 분업 구조예요 😊


정확합니다! 아주 잘 파악하셨어요 👍


DRF의 큰 흐름

[요청 들어올 때]
클라이언트 요청
    ↓
  View (1번째) ← 요청 받기, 어떤 데이터 꺼낼지 결정
    ↓
  Serializer   ← DB 데이터를 JSON으로 변환
    ↓
  View (2번째) ← JSON을 응답으로 반환
    ↓
클라이언트에 JSON 전달

일반 Django랑 비교하면

일반 Django:
클라이언트 → View(1번째) → Template → View(2번째) → 클라이언트

DRF:
클라이언트 → View(1번째) → Serializer → View(2번째) → 클라이언트

Template 자리에 Serializer가 들어간 것뿐이고,
View가 앞뒤로 두 번 역할 한다는 구조는 완전히 동일해요!


한 줄 요약

View = 교통정리 (앞에서 받고, 뒤에서 내보내고)
Serializer / Template = 중간 변환기 (데이터를 원하는 형태로 바꾸기)

이 큰 그림을 잡으셨으면 DRF 배울 때 훨씬 수월할 거예요 😊


Django REST Framework (DRF) 에서..

REST / Framework 단어 의미


🔤 REST

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 없이  →  칼, 도마, 냄비 직접 다 만들어서 요리
Framework 있으면 →  주방 도구 다 갖춰진 주방에서 요리만 집중

Django 자체도 Framework예요.
로그인, DB연결, URL 라우팅 등을 직접 처음부터 안 만들어도 되게 미리 준비해둔 것이죠.


🔤 정리

단어의미
RESTAPI 설계 규칙/약속
Framework미리 만들어놓은 편의 도구 모음
DRFREST 규칙을 따르는 API를 쉽게 만들 수 있게 도와주는 도구 모음

URL 라우팅이란?


🔤 라우팅 = "길 안내"

"이 URL로 요청이 들어오면, 어느 View로 보내줄지 결정하는 것"

실생활 비유로 보면

음식점 입구 직원 = 라우터

"혼자 오셨어요?" → 1번 테이블로 안내
"2명이요"        → 2번 테이블로 안내
"포장이요"       → 포장 카운터로 안내

🔤 Django에서 실제로 보면

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단계 : 환경 준비 (1~4번)

1. Python 설치 확인    → Django는 Python으로 돌아가니까 먼저 확인
2. 프로젝트 폴더 만들기 → 작업할 공간 생성
3. 가상환경 생성        → 이 프로젝트만의 독립된 환경 만들기
4. Django 설치         → 가상환경 안에 Django 설치

가상환경 = 프로젝트마다 별도의 방을 만드는 것
(A프로젝트 Django 3.0, B프로젝트 Django 5.0 따로 관리 가능)


🏗️ 2단계 : Django 프로젝트/앱 생성 (5~8번) 🔴

5. Django 프로젝트 생성  → 집 전체 뼈대 만들기
6. 서버 실행 확인        → 뼈대가 잘 만들어졌는지 확인
7. study 앱 생성        → 집 안에 "공부방" 만들기
8. settings.py 등록     → "나 study 앱 만들었어!" 라고 Django에 알리기

프로젝트 = 집 전체
앱 = 집 안의 각 방 (공부방, 거실, 주방...)


📁 3단계 : 폴더/모델 준비 (9~10번) 🔴

9. templates/static 폴더 준비 → HTML파일, CSS파일 저장할 폴더 만들기
10. Study 모델 작성            → DB 설계 (어떤 데이터를 저장할지)
# 모델 예시
class Study(Model):
    title <= 제목
    time  = 공부시간
    date  = 날짜

🗄️ 4단계 : DB 반영 & admin (11~14번)

11. 마이그레이션  → 모델을 실제 DB에 반영
12. admin 등록   → admin 페이지에서 Study 모델 관리할 수 있게 등록
13. 관리자 계정 생성      → admin 페이지 로그인 계정 만들기
14. 관리자 페이지에서 데이터 확인 → DB에 데이터 잘 저장되는지 확인

🔀 5단계 : URL 연결 (15~18번) 🔴

15. URL 구조 설계        → 어떤 URL을 만들지 계획
16. 프로젝트 urls.py 연결 → 집 대문에서 공부방으로 길 연결
17. 앱 urls.py 연결      → 공부방 안에서 세부 길 연결
18. 임시 View로 URL 확인  → URL이 View까지 잘 연결되는지 테스트
브라우저 요청
    ↓
프로젝트 urls.py  (대문)
    ↓
앱 urls.py       (공부방 문)
    ↓
View             (목적지)

🎨 6단계 : 화면 만들기 (19~22번) 🔴

19. base.html 작성          → 모든 페이지 공통 틀 만들기 (헤더, 푸터 등)
20. CSS 작성                → 페이지 꾸미기
21. 함수형 View로 목록페이지 구현 → DB 데이터 꺼내서 Template에 전달
22. 브라우저에서 최종 확인       → 완성된 페이지 확인

함수형 View란?


🔤 먼저 View가 하는 일 복습

요청 들어옴 → View가 처리 → 응답 돌려줌

이 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' ← 위에꺼 전부 자동으로 해줌

클래스형은 코드가 짧지만
내부에서 무슨 일이 일어나는지 안 보이죠


질문

  1. 함수형 View로 목록페이지 구현 → DB 데이터 꺼내서 Template에 전달
    이때 함수형 view는 무엇이고 원래는 어떤걸로 구성되어있는지 큰틀에서 기초적인 부분까지 알려줘

🎯 그래서 왜 이번 교안이 함수형으로 시작하냐면

함수형 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에 반영하면 엑셀 표처럼 생긴 테이블이 만들어져요

[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 페이지에서 입력칸으로 자동으로 나타나는 거예요!


📝 Form 구조에 필드가 들어간다는 의미

나중에 일반 사용자도 데이터를 입력할 수 있게
웹 페이지에 입력 폼을 만들게 되는데

[일반 사용자가 보는 화면]

공부 기록 추가

제목     : [ 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줄 추가

🔗 모델 → DB 연결 흐름

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 내장 필드 타입" 이라고 불러요


🔤 메서드 vs 클래스 차이

# 메서드 = 어떤 동작을 수행하는 함수
print()     ← 출력하는 동작
len()       ← 길이를 재는 동작

# 클래스 = 어떤 형태/틀을 정의하는 것
CharField()     ← "이 칸은 글자를 저장하는 칸이야" 라고 정의
IntegerField()  ← "이 칸은 숫자를 저장하는 칸이야" 라고 정의

🎯 왜 이런 클래스가 필요하냐면

# 그냥 이렇게만 쓰면 Django가 모름
title = ???   ← 이게 글자야? 숫자야? 날짜야?

# 필드 타입을 명시해줘야
title = CharField()    ← "글자 저장하는 칸"
hours = IntegerField() ← "숫자 저장하는 칸"

DB에 테이블을 만들 때 각 컬럼이 어떤 종류의 데이터를 저장할지 알아야 하기 때문이에요!


📋 자주 쓰는 Django 내장 필드 타입

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 내장 필드는?

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은 필수가 아니에요!


🎯 Admin의 정체

Admin = Django가 기본으로 제공하는 
        데이터 관리용 도구 (관리자 페이지)

🔄 이번 교안에서 Admin을 쓰는 이유

지금 상황
→ 아직 사용자가 데이터 입력하는 화면(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 vs Django DRF 프레임워크 차이


🤔 한 줄 요약

Django     → 웹 페이지(HTML) 를 만드는 프레임워크
Django DRF → 데이터(JSON) 를 주고받는 프레임워크

1️⃣ Django 프레임워크 과정

브라우저 요청
     ↓
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 페이지가 보임
화면 + 데이터 같이 반환

2️⃣ Django DRF 프레임워크 과정

브라우저/앱 요청
     ↓
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"
}

3️⃣ 핵심 차이점

Django                    Django DRF
──────────────────────────────────────────
HTML 반환                 JSON 반환
render()                  Response()
템플릿 필요               템플릿 불필요
Serializer 없음           Serializer 필수
브라우저만 사용           앱/웹 모두 사용

4️⃣ 파일 구조 차이

Django                    Django DRF
──────────────────────────────────────────
models.py      ✅         models.py      ✅
views.py       ✅         views.py       ✅
urls.py        ✅         urls.py        ✅
templates/     ✅         templates/     ❌ 불필요
serializers.py ❌ 없음    serializers.py ✅ 추가됨

5️⃣ views.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 자동 반환!

6️⃣ URL 설정 차이

# 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/    삭제

7️⃣ Serializer란?

DRF에만 있는 핵심 개념!

DB 데이터                  JSON
────────────────────────────────
<Todo: 공부하기>  →  {"name": "공부하기"}
(Python 객체)         (JSON 데이터)

역할
────────────────────────
① 데이터 변환 (Python ↔ JSON)
② 데이터 유효성 검사
③ 데이터 저장
class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo           # 어떤 모델?
        fields = "__all__"     # 어떤 필드?

8️⃣ 언제 뭘 쓰나?

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     = 재료(데이터)만 제공 🥩
         (요리는 앱/프론트가 함)

공부기록프로젝트 2편 코드분석 시작~

https://velog.io/write?id=f38a7a87-f649-477d-922b-d65bf9720f0b

  1. 1편 상태 먼저 점검하기

모델 데이터가 중요 --> URL --> VIEW --> TRMPLETE

VIEW는 많은역할을 함 그래서 1편에서 2편으로 넘어갈때 코드가 동일한지 확인체크


ModelForm을 만들고, 함수형 View 기준으로 공부기록 생성(Create), 상세(Detail), 수정(Update), 삭제(Delete), 페이지네이션까지 완성하며 브라우저 기반 CRUD 흐름을 자세히 익힙니다.


Django CRUD 각 기능 역할


  1. ModelForm 만들기
# 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 vs POST 차이

핵심 차이

GETPOST
용도데이터 조회데이터 전송/저장
데이터 위치URL에 노출Body에 숨겨짐
보안낮음높음
데이터 크기제한 있음제한 없음
캐싱가능불가능

눈으로 보는 차이

# GET - URL에 데이터가 보임
https://example.com/search?keyword=python&page=1

# POST - URL에 데이터가 안 보임
https://example.com/login
(아이디/비밀번호는 숨겨져서 전송)

Django에서 사용 예시

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 로 기억하세요!


질문 장고에서의 모델 폼에대한 설명과 사용쓰임방법

Django ModelForm 완벽 정리

ModelForm이란?

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})

핵심 차이점

FormModelForm
필드 정의직접 작성모델에서 자동 생성
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 연동까지 자동으로 해줍니다.



질문 답변

Form / ModelForm을 쓰는 이유 나의질문 폼이랑 모델폼차이가 이해가 안되신다는건가용??

Study 모델 정의
→ ModelForm 작성
→ 폼에서 입력값 검증
→ form.save()로 모델 저장

답변

  • 스터디 모델을 1편에서 만들었잖아요?
    그 모델이랑 연결되는 form을 만들라는거에용
    모델과 연관성있는 것 무언가 입력을 받는 구조의 폼이라고 생각

  • Form은
    그냥 입력창을 만드는 도구
    어떤 값을 받을지 직접 다 적어줘야 함
    저장도 직접 해야 함

즉, “입력만 받는 일반 양식”이라고 이해하시면 됩니다.

  • ModelForm은
    모델을 기준으로 폼을 쉽게 만드는 도구
    모델 필드를 바탕으로 입력창을 만들 수 있음
    검증도 도와주고, form.save()로 DB 저장도 쉬움

즉, “모델이랑 연결된 폼”이라고 이해하시면 됩니다.

  • 우리가 템플릿에서 보는 태그는
    사용자가 값을 입력해서 보내는 HTML 영역이에요!

  • 사용자가 입력한 값이 서버로 전달되면,
    서버에서 ModelForm이 그 값을 받아 검증하고,
    문제가 없으면 저장한다고 생각하시면 됩니당


나의질문

study 앱에 폼을 만들고 그 폼이라는것은 그냥 앱 생성할때마다 만드는 폼이라고 생각하면되나요.. 그리고 그안에 CRUS페이지까지 스터디앱에 만드는거죠?

답변

폼은 앱 만들 때 무조건 만드는 게 아니라, 사용자의 입력을 받아야 할 때 만드는 거예요! 항상 만드는건 아니에용 그리고 Study 앱을 만들었으니까, Study 관련 CRUD 페이지도 그 앱 안에서 같이 만듭니다


Form vs ModelForm 적용 범위

아니요, 둘 다 모델 파일과 독립적으로 사용할 수 있습니다.


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은 모델 없이 어디서든 독립적으로 사용할 수 있습니다.


1. 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

2. "메서드"라는 표현에 대해

정확히는 구분해서 불러야 합니다.

용어설명예시
클래스(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 메서드야?" 라고 하면 엄밀히는 클래스라고 표현하는 게 맞습니다.


5. 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가 반복적인 폼 작업을 자동화해주기 위해 만든 강력한 내장 기능입니다!

2. 생성 (Create)

사용자가 폼에 데이터 입력 → DB에 새 데이터 저장
예) 게시글 작성, 회원가입

새로운 데이터를 추가하는 기능

3. 상세 (Detail)

목록에서 항목 클릭 → 해당 데이터 상세 내용 표시
예) 게시글 본문 보기

특정 데이터 하나를 자세히 조회하는 기능

4. 수정 (Update)

기존 데이터를 불러와 폼에 표시 → 수정 후 저장
예) 게시글 편집

기존 데이터를 변경하는 기능

5. 삭제 (Delete)

특정 데이터 선택 → DB에서 완전 삭제
예) 게시글 삭제

데이터를 DB에서 제거하는 기능

6. 페이지네이션 (Pagination)

데이터가 많을 때 → 한 페이지에 n개씩 나눠서 표시
예) 1페이지, 2페이지, 3페이지...

많은 데이터를 나눠서 보여주는 기능

전체 흐름 요약

ModelForm        → 입력 폼 자동 생성
Create (생성)    → 데이터 추가 (INSERT)
Detail (상세)    → 데이터 1개 조회 (SELECT)
Update (수정)    → 데이터 변경 (UPDATE)
Delete (삭제)    → 데이터 제거 (DELETE)
Pagination       → 데이터 분할 표시

💡 이 6가지가 합쳐지면 브라우저 기반 CRUD 완성입니다!


왜 이 순서인가?

이 순서는 기능을 그냥 나열한 것이 아닙니다.

예를 들어:

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


2번 하기전 준비


  1. 생성(Create) 기능을 만들기 전에 URL부터 추가하기

path() 구조 분석
pythonpath('', views.study_list, name='list')
path(경로, 뷰함수, name=이름) — 총 3개의 인자로 구성됩니다.

1. 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() = "연결된 모델에 알아서 넣고 저장해줘" 라는 명령

  1. 코드 구조 정체
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가 클래스 밖에 있으면 → 함수, 클래스 안에 있으면 → 메서드

  1. 생성(Create) View 작성
    어려움

이제 study_create View를 추가합니다.

  1. 생성 / 수정 공용 폼 템플릿 만들기

HTML 템플릿 큰 그림 분석

1. 상속 구조

{% extends 'base.html' %}
  • 이 파일은 base.html을 부모로 삼음
  • 즉, base.html의 공통 레이아웃(헤더, 푸터 등)을 그대로 가져오고
  • 다른 부분만 여기서 채워 넣는 구조

2. block 2개

{% block title %}
    {{ page_title }} | 공부시간 기록기
{% endblock %}

{% block content %}
    ... 실제 내용 ...
{% endblock %}
  • block = base.html에 뚫어놓은 구멍
  • 이 파일이 그 구멍을 채워넣는 역할
  • title → 브라우저 탭 제목
  • content → 실제 화면에 보이는 내용 전체

3. 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>

4. 폼 필드 패턴 (반복구조)

모든 필드가 똑같은 패턴으로 반복됩니다

<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검증 실패시 에러 출력

5. 특이한 부분 2가지

① 시간/분 나란히 배치

<div class="form-row inline-2">
    <div> 시간 입력 </div>
    <div> 분 입력 </div>
</div>
  • inline-2 클래스로 두 개를 가로로 나란히 배치

② 보안 토큰

<form method="post">
    {% csrf_token %}
  • POST 요청시 반드시 필요
  • 없으면 Django가 요청을 거부함
  • 외부에서 악의적인 요청을 막는 보안 장치

전체 흐름 한줄 요약

base.html 레이아웃 상속
    → 소개 영역 (hero-card)
    → 폼 영역 (content-card)
        → 필드마다 라벨 + 입력창 + 에러메시지 패턴 반복
        → 저장 or 목록으로 버튼
  1. CSS에 폼 관련 스타일 추가하기

  2. 브라우저에서 생성 기능 먼저 확인하기

  1. 상세(Detail) 기능을 만들기 전에 URL 추가하기
  1. 상세(Detail) View 작성
  1. 상세 페이지 템플릿 만들기
  1. 목록 페이지에 상세 보기 링크 연결하기
profile
개발언어를 배우는 과정 기록

1개의 댓글

comment-user-thumbnail
2026년 4월 10일
  • 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는 화면/요청 처리 방식의 차이예요.

답글 달기