💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    1. 공식문서를 통한 DRF 설치 | ✅저자: 이유정(박사)

    📖 공식 문서 링크:
    🔗 https://www.django-rest-framework.org/#installation


    🔹 DRF(Django REST Framework)는 Django 웹 앱을 API 서버로 만들어주는 강력한 확장 도구입니다.

    ❓왜 DRF가 필요한가? Django는 기본적으로 HTML 웹사이트를 만드는 데 최적화되어 있습니다.
    하지만 요즘은 웹사이트뿐 아니라 다음과 같은 API 서버가 많이 필요합니다.

    • 모바일 앱과 연결되는 백엔드
    • React/Vue 같은 프론트엔드와 통신
    • 외부 서비스에 데이터를 제공하는 API
    • JSON, XML 등으로 응답하는 데이터 시스템

    여기서 필요한 게 바로 REST API입니다. Django만으로도 API는 만들 수 있지만:

    • 인증, 권한, 직렬화, 예외 처리 등 모든 걸 직접 구현해야 하고,
    • 코드가 장황하고 복잡해집니다.

    그래서 등장한 게 DRF입니다

    🤔DRF가 하는 역할:

    • 직렬화 (Serializers) Python 객체 → JSON 응답 / JSON → Python 변환
    • 인증 & 권한 시스템 로그인한 사용자만 POST 가능 같은 제어
    • Class-based View 지원 API View를 CBV로 깔끔하게 구성
    • Router 자동 URL 연결 ViewSet만 정의하면 URL이 자동 생성됨
    • Browsable API 지원 웹에서 테스트 가능한 API 화면 자동 생성
    • 자동 테스트 & 문서화 Swagger/OpenAPI 문서 자동 생성 가능

    🔹 Django vs DRF 비교

    Django: HTML 템플릿 방식

    사용자가 form으로 (GET/POST) 브라우저 요청 
           ↓
    Django View 함수/클래스/제너릭뷰
           ↓
    Model에서 데이터 조회 or 저장
           ↓
    context에 담아 템플릿에 전달
           ↓
    템플릿(HTML) 렌더링 (render)
           ↓
    HTML 페이지를 브라우저에 응답
    

    DRF: JSON API 방식

    프론트엔드 요청 (axios / fetch / Insomnia / postman 등)
           ↓
    DRF APIView / GenericAPIView / ViewSet
           ↓
    Model에서 데이터 조회 or 저장
           ↓
    Serializer로 직렬화 (또는 역직렬화)
           ↓
    JSON 응답 (Response)
           ↓
    프론트엔드에서 axios를 통해 JSON을 받아 화면 구성
    

    📖 용어설명: axios / fetch / Insomnia : API 요청 도구 (브라우저 JS 또는 테스트 도구) APIView / GenericAPIView : DRF에서 기본 뷰 클래스 (직접 제어 가능) ViewSet : CRUD를 한 클래스로 묶은 추상화된 구조 views.py Model : 데이터베이스의 실제 객체 views.py Serializer : 모델 ↔ JSON 변환 (직렬화/역직렬화) 프론트엔드에서 렌더링 : 받은 JSON을 React/Vue/Javascript 등에서 DOM으로 출력

    DRF의 전체 흐름

    1. 사용자 입력 (input, textarea)
           ↓
    2. axios가 JSON으로 변환하여 서버로 전송 (POST/PUT)
           ↓
    3. DRF View (APIView / ViewSet 등) 도착
           ↓
    4. Serializer가 JSON 데이터를 역직렬화하여 Python 객체로 변환 
           ↓
    5. 유효성 검사 후 → Model.save() → DB에 저장
           ↓
    6. 이후에 사용자가 다시 데이터를 요청 (예: 목록 보기)  
           ↓
    7. axios가 GET 요청으로 서버에 요청
           ↓
    8. DRF View가 Model 인스턴스를 조회하고 → Serializer가 직렬화하여 JSON으로 변환
           ↓
    9. JavaScript가 받은 JSON을 기반으로 HTML(DOM)을 구성
           ↓
    10. 자바스크립트가 `<input>`, `<textarea>` 등을 만들어 브라우저에 표시
    

    (Todo)을 기준으로 Django 방식(HTML) 과 DRF 방식(JSON) 의 전체 흐름을 짧은 코드로 비교 설명:

    models.py

    from django.db import models
    
    class Todo(models.Model):
        todaywork = models.CharField(max_length=100)
    
        def __str__(self):
            return self.todaywork
    

    🔸 Django 방식 (HTML 템플릿 기반) 사용자가 form에 입력 → 서버가 DB 저장 → 다시 HTML로 목록을 렌더링

    urls.py

    from django.urls import path 
    from .views import TodoCreateView, TodoListView  
    
    urlpatterns = [ 
    
    path('todo/create/', TodoCreateView.as_view(), name='todo_create'), 
    
    path('todo/', TodoListView.as_view(), name='todo_list'), 
    
    ]
    

    views.py

    from django.views.generic import CreateView, ListView 
    from .models import Todo  
    
    class TodoCreateView(CreateView):     
    	model = Todo     
    	fields = ['todaywork']     
    	template_name = 'todo_form.html'     
    	success_url = '/todo/'  
    	
    class TodoListView(ListView):     
    	model = Todo     
    	template_name = 'todo_list.html'     
    	context_object_name = 'todos'
    

    todo_form.html (템플릿)

    <form method="post">   
    	{% csrf_token %}   
    	{{ form.as_p }}   
    	<button type="submit">저장</button> 
    </form>
    

    todo_list.html (템플릿)

    <ul>   
    	{% for todo in todos %}     
    	<li>{{ todo.todaywork }}</li>   
    	{% endfor %} 
    </ul>
    

    🔸 DRF 방식 (JSON API + JS 화면 구성) 사용자가 input에 입력 → JS가 axios로 JSON 전송 → DRF가 저장 → JS가 다시 목록 요청 → 화면에 표시

    urls.py

    from django.urls import path 
    from .views_api import TodoListCreateAPI  
    
    urlpatterns = [     
    	path('api/todos/', TodoListCreateAPI.as_view(), name='todo_api'), 
    ]
    

    serializers.py

    from rest_framework import serializers 
    from .models import Todo  
    
    class TodoSerializer(serializers.ModelSerializer):     
    	class Meta:         
    	model = Todo         
    	fields = ['id', 'todaywork']
    

    views_api.py

    from rest_framework import generics 
    from .models import Todo 
    from .serializers import TodoSerializer  
    
    class TodoListCreateAPI(generics.ListCreateAPIView):
    	queryset = Todo.objects.all()     
    	serializer_class = TodoSerializer
    

    index.html (JS 포함)

    <body>
      <input type="text" id="todoInput" />
      <button onclick="addTodo()">추가</button>
      <ul id="todoList"></ul>
    
      <script>
      // 새로운 할 일을 추가하는 함수
      function addTodo() {
        // 입력창에서 사용자가 작성한 값 가져오기
        const value = document.getElementById('todoInput').value;
        
        // 서버에 POST 요청으로 새 todo 데이터 전송
        axios.post('/api/todos/', { todaywork: value })
          // 추가가 성공하면 전체 목록 다시 불러오기
          .then(getTodos);
      }
    
      // 전체 할 일 목록을 서버에서 가져오는 함수
      function getTodos() {
        // GET 요청으로 할 일 목록 받아오기
        axios.get('/api/todos/').then(response => {
          // 할 일 목록을 보여줄 HTML 요소 선택
          const list = document.getElementById('todoList');
    
          // 기존 목록을 초기화 (중복 방지)
          list.innerHTML = '';
    
          // 받아온 데이터(todo 배열)를 하나씩 순회
          response.data.forEach(todo => {
            // <li> 요소 생성
            const li = document.createElement('li');
    
            // <li> 안에 할 일 텍스트 넣기
            li.textContent = todo.todaywork;
    
            // 목록에 <li> 추가 li를 리스트(list)에 붙이는 것
            list.appendChild(li);
          });
        });
      }
    
      // 페이지 처음 로딩될 때 할 일 목록 자동 호출
      getTodos();
    </script>
      <script src=
      "https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    </body>
    
    • 아이디 선택자: document.getElementById("아이디명");
    • 클래스 선택자: document.getElementsByClassName("클래스명");
    • 태그 선택자: document.getElementsByTagName("태그명");
    핵심 구분 Django 기본 방식 DRF 방식
    요청 방식 form 제출 axios 호출
    처리 위치 views.py + Form views_api.py + Serializer
    응답 방식 HTML JSON
    views.py는 관례일 뿐이고, 다른 이름을 써도 되지만 반드시 urls.py에서 import를 명확히 해야합니다.

    🔹 DRF용어 및 개념

    • APIView : Django의 View처럼 API 응답을 만드는 클래스
    • Serializer : 모델 데이터를 JSON으로 바꾸는 도구
    • ViewSet : CRUD를 자동으로 묶어주는 API 뷰
    • Router : ViewSet과 연결되어 URL을 자동으로 생성
    • Permissions : 누구나, 인증된 사용자만 등의 접근 제어
    • Authentication : 로그인 / 토큰 인증 / 세션 인증 등을 처리
    • Browsable API : 웹 브라우저로 API를 쉽게 테스트 가능하게 함

    🔹 DRF를 언제 쓰면 좋은가요?

    • 모바일 앱과 연결되는 백엔드가 필요할 때
    • React/Vue 같은 프론트와 데이터 주고받을 때
    • JSON API 서버가 필요할 때
    • 빠르고 유지보수 쉬운 REST API를 만들고 싶을 때

    튜토리얼은 “Snippet API”라는 프로젝트를 통해 RESTful API를 구현하는 전체 과정을 보여줍니다.

    사용자가 코드 조각(snippet)을 작성하여 서버에 저장하고,
    JSON 형식으로 데이터를 주고받으며,
    사용자 인증도 적용할 수 있는 API 서버를 만드는 것이 목표입니다.


    ✅ 가상환경 설정

    # 1. 프로젝트 디렉토리 만들기
    mkdir drf_tutorial
    cd drf_tutorial
    
    # 2. 가상환경 생성
    python -m venv venv
    
    # 3. 가상환경 활성화 (운영체제별 다름)
    macOS / Linux / WSL
    source venv/bin/activate
    

    ✅ Django 및 DRF 설치

    pip install django
    pip install djangorestframework
    

    선택적설치: 장고 서드파티 부분

    pip install markdown       # Markdown 지원 (Browsable API용)
    pip install django-filter  # 필터 기능 추가 (추후 사용 가능)
    

    markdown은 Python용 Markdown 처리 라이브러리입니다. #제목 \n **굵은글씨** 같은 마크다운 문자열을 → HTML로 변환해줍니다.


    django-filter : Django 공식 서드파티 라이브러리입니다. 목적은 쿼리셋에 대한 필터링(검색, 조건조회) 기능을 아주 간단하게 구현하게 도와주는 도구입니다. DRF가 아닌 순수 Django 프로젝트에서도 ListView 등에서 활용할 수 있습니다.


    ✅ Django 프로젝트 만들기

    # 새 프로젝트 생성
    django-admin startproject tutorial .
    
    # 새 앱 생성
    python manage.py startapp snippets
    

    ✅ settings.py 설정 tutorial/settings.py 파일에서 아래 2가지 설정을 추가합니다.

    INSTALLED_APPS = [
        ...
        'rest_framework',  # DRF 필수 앱 등록
        'snippets',        # 우리가 만든 앱 등록
    ]
    

    ✅ URL 설정 tutorial/urls.py 파일을 수정:

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
    	path('admin/', admin.site.urls),
        path('', include('snippets.urls')),
    ]
    

    ✅ 설치가 잘 되었는지 확인:

    python manage.py runserver
    
    접속 주소: http://127.0.0.1:8000/
    

    ✅ gitHub와 연결 및 commit

    # Git 초기화
    git init
    
    # 브랜치 이름을 바로 Eunice로 지정
    git checkout -b Eunice
    
    # 커밋할 임시 파일 만들기
    touch README.md
    
    # Git에 추가하고 커밋
    git add README.md
    git commit -m "Initial dummy commit for Eunice branch"
    
    # 원격 저장소 연결
    git remote add origin https://github.com/handgonpo/레파지토리.git
    
    # 푸시
    git push -u origin Eunice
    

    git init : 로컬 프로젝트 디렉토리를 Git 저장소로 초기화 .gitignore 설정 : - 추적하지 않을 파일 지정 (예: .env, __pycache__/, db.sqlite3 등) - 보안에 민감한 API키(.env) - 개인개발환경에서만 생성되는 임시파일 __pycache__/.DS_Store - 용량절약: db.sqlite3 DB는 자주 바뀌고 용량이커서 버전 관리에 부적 - 협업방지: 개발자마다 개발환경이 다르므로 로컬설정을 고유하면 오류 git add . : 모든 변경 사항을 Git 스테이징 영역에 추가 git commit -m "처음 커밋" : 커밋 메시지는 반드시 입력해야 커밋이 됩니다. 커밋메시지는 변경사항의 의미를 적어서 기록에 남긴다. git remote add origin 깃헙주소 : GitHub 원격 저장소 연결 (한 번만 설정하면 됨) git branch -M main` : 브랜치를 main으로 명명 (기본 브랜치 명 통일용)

    git checkout -b Eunice        # 새 브랜치 생성
    git push origin Eunice        # GitHub에 푸시
    

    브런치를 자신의 이니셜로 바꾸면 협업, 분류, 관리 측면에서 매우 실용적입니다

    git push -u origin main : 원격 저장소에 처음으로 푸시 (앞으로는 git push만 해도 됨)

    초기 설정 이후 커밋하는 방법: 터미널에서 CLI로 입력하는 방법과 VSCode 이용 ◾ Git Commit :

    # 전체 파일 add 
    git add .
    
    # 커밋 메시지 작성
    git commit -m "전달할 메시지"
    

    ◾ GitHub에서 수정한 내용을 VSCode로 가져오는 방법:

    # 현재 브랜치 확인
    git branch
    
    # 현재 브랜치가 'Eunice' 라면:
    git pull origin Eunice
    

    ◾ VSCode에서 Commit & Push

    TOP
    preload preload