Search

django 정리

✅ 목차

❓ django 란?

장고(django)MVF 패턴을 따르는 프레임워크이며, Flask와 함께 python의 대표적인 웹 프레임워크이다.

❓ MVT 패턴이란?

사용되는 목적은 다른 웹 프레임워크에서 채택한 방식인 MVC 패턴과 동일하다.
여러 목적을 가진 다양한 코드한 위치에 보관 & 관리 되면서, 하나의 기능을 편집 시에도 전체의 서비스가 영향을 받는 상황이 많이 발생하였다.
이를 방지하기 위해 MVC, MVT 같은 방식을 채택한 웹 프레임 워크가 등장하게 되었다.
MVT패턴Model-Template-View의 약자이다.
Model : 데이터에 대한 단 하나의 정보의 소스이며, 저장하고 있는 데이터의 필수적인 필드와 동작을 저장하고 있다.
from django.db import models class Person(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30)
Python
Template : MVC에 Controller가 있다면, MVT에는 Template가 있다.
프리젠테이션 계층 역할을 하며 기본적으로 데이터를 렌더링하는 HTML 코드를 사용한다.
<html lang="en"> <head> <meta charset="UTF-8"> <title>NAME INFO</title> </head> <body> 성 : {{ person.first_name }} <br> 이름 : {{ person.last_name }} <br> </body> </html>
HTML
View : 사용자에게 데이터를 보여주기 위한 부분이다.
from django.http import HttpResponse from django.views import View class MyView(View): def get(self, request, *args, **kwargs): return HttpResponse('Hello, World!')
Python

⚙️ Django 설치

python을 사용하는 웹 프레임워크이기 때문에, 당연히 Python은 설치(3.x)되어야 한다.
본인은 개인적으로 Anaconda를 활용한 파이썬 가상환경을 사용하여 관리하는 것이 편하기 때문에, Anaconda를 사용할 것이다.
😎
Anaconda의 기본적인 사용법이 궁금하다면 이 링크에 Anacoda 관련 글을 작성해두었으니 참고하자
1.
새로운 가상환경 설치
conda create -n django python=3.8
Bash
2.
생성한 가상환경 실행
정상적으로 실행되면 아래 이미지처럼 가상환경 이름(django) 가 붙는다.
conda activate django
Bash
3.
가상환경이 활성화 된 상태에서 pip 를 사용하여 django 를 설치한다.
pip install django
Bash
4.
정상적으로 설치가 완료되었다면 아래 이미지처럼 python shell에서 django import 후, django.get_version() 명령어로 버전 확인이 가능하다.

🏗️ Django로 사이트 만들어보기

⚠️
지금부터 작성하는 게시판 사이트 만들기 예제는 참고자료에 작성한 [ django의 특징과 예시 사이트 제작 ] 블로그 & 강의를 보며 따라한 내용이 매우 많습니다. 더 자세한 내용은 원 블로그 작성자의 URL을 참고하는것이 가장 좋고, 권장드립니다.

🛠️ 프로젝트 생성

django에서는 django-admin 커맨드startproject 라는 서브 커맨드를 사용하여 프로젝트를 만든다.
😎
당연한 말이지만, 프로젝트 이름은 본인 맘대로 하면된다. 더 자세한 명령어 옵션을 알고싶다면, django-admin startproject -h 를 입력하여 확인하자.
⚠️
또한, 해당 명령어 실행 위치에 프로젝트 폴더가 생성되니 미리 원하는 위치로 이동 후 사용해야한다.
# django-admin startproject [ project name ] django-admin startproject toyproject
Bash
정상적으로 설치되었다면, 아래와 같은 구조를 가지는 프로젝트 파일이 생성된다.

🌳 프로젝트 폴더의 구조

위 과정을 통해 django 사이트를 만들기 위한 프로젝트 폴더를 생성해봤다.
그런데 폴더 속 내용을 확인하니, 기본적으로 생성된 폴더 & 파일이 존재하는데 어떤 기능을 하는 걸까? 하나씩 알아보자.
생성 직후 프로젝트 폴더 구조 🌳
./toyproject ├── manage.py └── toyproject ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py
Bash
manage.py : django-admin 을 사용하여 프로젝트 생성 시, 자동으로 추가되는 파일이다.
django-admin과 동일한 작업을 수행하지만 manage.pyDJANGO_SETTINGS_MODULE 가 존재하기 때문에, 현재 장고 프로젝트의 setting.py 값을 알려주는 역할을 한다.
toyproject(toyproject DIR) : django-admin 을 사용하여 생성한 프로젝트와 동일한 이름을 가지며, 프로젝트를 위한 실제 Python 패키지들이 저장한다.
toyproject/__init__.py : 이 디렉토리를 패키지처럼 다루라고 알려주는 용도의 단순한 빈 파일
⚠️
파이썬에서 특정 디렉터리를 패키지의 일부임을 알려주기 위해서는 __init__.py 라는 파일이 존재해야 한다. (python3.3 부턴 안써도 된다곤 하지만...) → python wikidocs.net 관련 내용
toyproject/asgi.py : ASGI(Asynchronous Server Gateway Interface)와 연결하여 웹 서버를 실질적으로 구동 가능하도록 도와주는 파일이다. (예제 프로젝트 할때는 굳이 깊게 안봐도 될듯 하다)
😎
ASGI이와 비슷한 인터페이스인 WSGI에 대한 설명을 상세히 작성해주신 글의 링크를 걸어두겠다. 궁금한 사람은 확인하면 좋은 내용이라 생각한다. → ASGI와 WSGI 에 대한 블로그 내용
toyproject/settings.py : 현재 Django 프로젝트의 환경 및 구성을 저장하는 파일이다.
😎
공식 문서에 Django settings에 관한 내용이 있다. 역시나 궁금한 사람은 확인해보면 좋다. → Django settings in Django Docs
toyproject/urls.py : Django project 의 URL 선언(매핑)을 저장한다.
간단히 말해서 url로 접속 시, 입력한 url에 따라 어떤 view에 매핑할지 작성해둔 코드이다.
toyproject/wsgi.py : 여기(asgi.py)에도 설명했지만, 이 파일은 WSGI에 관한 파일이다.

🏃‍♂️ 프로젝트 생성 후 실행법

아직 아무 기능도 없지만, 서버를 먼저 실행해 볼 것이다. 좀 전에 봤던 manage.py 파일과 runserver 를 사용한다.
⚠️
당연히 프로젝트 폴더 위치로 이동해야한다. 해당 위치에 manage.py 파일이 존재하기 때문이다.
# runserver뒤에 원하는 포트번호를 설정할 수 있다. # 기본은 8000번 ./manage.py runserver [port 번호] # ./manage.py test를 사용하여 실행하지 않고 테스트만 가능하다. ./manage.py test
Bash
만약 정상적으로 실행됬다면, 아래와 같이 동작하며 127.0.0.0:port 에 접속하면 오른쪽과 같이 Django 페이지를 확인할 수 있다.
혹시 아래와 같이 Error: That port is already in use. 에러가 발생하며 정상적으로 동작하지 않는다면, 이미 다른 프로그램에서 해당 포트(기본 8000번) 포트를 사용하는 것이기 때문에 포트를 확인해야 한다.

🔨 프로젝트에 App 생성

Django 프로젝트 내부에 여러 App을 생성하여 기능별로 관리가 가능하다.
한 Django 프로젝트 속 여러 App들이 모여 하나의 프로젝트를 이루는 것이다.
마찬가지로 manage.py 파일을 사용하며, 이번엔 startapp 명령어를 사용한다.
# manage.py startapp [app 이름] ./manage.py startapp bbs
Bash
정상적으로 생성되었다면, 프로젝트 폴더 속에 아래와 같은 구조를 가지는 app 이름을 가진 폴더가 생성된다.

🌳 APP 폴더의 구조

위 과정을 통해 django 프로젝트의 App 폴더를 생성해봤다.
이번에도 기본으로 생성된 여러 폴더 & 파일이 있는데, 하나씩 확인해보자.
생성 직후 APP 폴더 구조 🌳
./bbs ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py
Bash
__init__.py : 프로젝트 폴더에도 존재하는 파일이며, 프로젝트 폴더 부분 설명과 같다.
admin.py : 어드민 설정파일이다.
apps.py : App의 설정파일이다.
migrations(migrations DIR) : 마이그레이션 시, 변경사항에 대한 정보를 저장하는 곳
마이그레이션은 모델에 대한 변경 사항을 데이터베이스 스키마에 전달하는 Django의 방법이다.(필드 추가, 모델 삭제 등)
__init__.py : 프로젝트 폴더에도 존재하는 파일이며, 프로젝트 폴더 부분 설명과 같다.
models.py : App의 모델 파일이다. 해당 앱의 데이터를 SQL문을 사용하여 직접 테이블을 설계하지 않고저장할 데이터베이스를 장고 ORM을 통해 모델화하는데 이때 사용되는 파일이다.
ORM(Object-Relational Mapping) 이란? 객체(Object)와 관계형 DB의 데이터를 매핑해주는 것이다. 즉 객체 간의 관계를 사용하여 SQL구문을 자동으로 생성하며, 직접 SQL 쿼리문을 작성할 필요 없이 데이터를 다룰 수 있는 방법이다. → ORM 개념에 대한 설명과 예시를 잘 설명해주신 블로그
tests.py : App 내부의 기능을 테스트하는 기능을 구현하는 파일이다.
views.py : 앱의 직접적인 화면(template)데이터(model) 사이에서 사용자의 요청을 처리하여 모델에 저장 후, 이 데이터를 화면(template)에 전달하는 다리 역할을 하는 view에 관한 기능을 구현한 파일이다.

😎 간단한 접속 페이지 만들기

지금은 model을 사용하여 데이터를 다루는 부분은 아니므로 아래와 같은 순서로 진행한다.
1.
toyproject/urls.py 파일에서 매핑되는 주소 설정
2.
/bbs/views.py : VIEW 기능을 설정(template과 연결)
지금은 보여줄 내용(화면)을 직접 반환할 것이다. 아직은 model을 사용하여 데이터를 다루지 않기 때문에, 여기서는 template을 사용하지 않는다.

1. VIEW 기능을 설정

먼저 /home 경로에 접속 시 사용될 home 핸들러를 /bbs/views.py 파일에 만들어 줘야 한다.
처음에는 아무 핸들러가 없기 때문에 아래와 같은 내용 뿐이다.
수정 전
from django.shortcuts import render # Create your views here.
Python
함수 home 을 만들어 request 를 인자로 받은 후, HttpResponse 를 사용하여 접속 시 메세지를 반환하도록 만든다.
수정 후
핸들러의 첫 번째 인자는 반드시 request 이다. 이 인자를 활용하여 접속 시 요청 정보를 얻기 때문이다. 또한 핸들러는 반드시 반환이 필요하다.
from django.shortcuts import render from django.http import HttpResponse # home 핸들러를 선언합니다. def home(request): # HttpResponse 함수를 사용하여 메세지를 반환합니다. return HttpResponse('THIS IS HOMEPAGE!')
Python

2. 매핑되는 주소 설정

처음 toyproject/urls.py 에 접속하면 아래와 같은 내용이다.
아직은 admin 페이지 접속 경로만 설정되어 있다.
수정 전
from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ]
Python
먼저, /bbs/views.pyhome 핸들러를 참조할 수 있도록 가져와준다.
이후 path 함수를 사용하여 /home 경로와 매핑될 핸들러를 설정해준다.
수정 후
from django.contrib import admin from django.urls import path # /bbs/views.py 의 home 핸들러 참조 from bbs.views import home urlpatterns = [ # /home에 접속하면 views.py에 정의된 home 핸들러가 실행되도록 한다. path('home/', home), path('admin/', admin.site.urls), ]
Python

3. 서버 실행 후 확인

서버를 실행 후 정상적으로 실행된다면 아래와 같이 /home 에 접속 시 메세지를 확인할 수 있다.

😎 간단한 접속 페이지 만들기 [응용]

위 과정에서 간단한 접속 페이지를 만들어 봤다. 하지만 url접속 시 항상 고정된 url만 접속하지 않는다.
예를 들어 특정 게시글의 내용을 볼때는 /view/1 과 같이 번호를 url에 입력하여 접속하기도 하니 말이다.

1. url 경로에 키워드 인자를 받도록 수정

위 과정을 통해 사이트를 만들었다면 urls.py 는 아래와 같은 내용일 것이다.
수정 전
from django.contrib import admin from django.urls import path # /bbs/views.py 의 home 핸들러 참조 from bbs.views import home urlpatterns = [ # /home에 접속하면 views.py에 정의된 home 핸들러가 실행되도록 한다. path('home/', home), path('admin/', admin.site.urls), ]
Python
path('home/', home)키워드 인자를 받을 수 있도록 아래와 같이 코드를 수정해준다.
수정 후
from django.contrib import admin from django.urls import path # /bbs/views.py 의 home 핸들러 참조 from bbs.views import home urlpatterns = [ # /home에 접속하면 views.py에 정의된 home 핸들러가 실행되도록 한다. # 또한 <str> 이라는 키워드 인자를 입력받아 핸들러에 전달해줄 수 있다. path('home/<str>', home), path('admin/', admin.site.urls), ]
Python

2. 핸들러에서 키워드 인자를 받도록 수정

위 과정을 통해 사이트를 만들었다면 view.py 는 아래와 같은 내용일 것이다.
수정 전
from django.shortcuts import render from django.http import HttpResponse # home 핸들러를 선언합니다. def home(request): # HttpResponse 함수를 사용하여 메세지를 반환합니다. return HttpResponse('THIS IS HOMEPAGE!')
Python
view.py 에 작성된 home 핸들러의 인자에서 urls.py 에서 추가한 str 키워드를 인자로 받도록 수정한다.
또한 str 값이 반환되는 메세지에 보이도록 적용해준다.
수정 후
from django.shortcuts import render from django.http import HttpResponse # home 핸들러를 선언합니다. def home(request, str): # HttpResponse 함수를 사용하여 메세지를 반환합니다. # urls.py에서 적용한 str 키워드 값이 home 핸들러의 인자로 사용되며, 해당 값을 반환메세지에 적용 return HttpResponse('THIS IS {}!'.format(str))
Python

3. 서버 실행 후 변경된 내용 확인해보기

이번에는 str 키워드 확인을 위해 /home/MYSTR 이라는 경로로 접속해보았다.
정상적으로 코드가 적용됬다면 아래와 같이 입력한 키워드를 확인할 수 있다.

🗒️ 게시판 사이트 만들기 [ MODEL 설정 ]

이제는 실제 데이터를 다루는 예시 사이트, 게시판 사이트를 만들어본다.
게시판 사이트는 글에 대한 데이터를 다루기 때문에, Model을 만들어 적용해볼 수 있다.
🗒️ 게시판 기능 목록
게시글 목록 확인
게시글 상세 내용 확인
게시글 작성
게시글 수정
게시글 삭제

1. 모델(Model) 생성

게시글에는 제목(title), 게시글 내용(content), 작성자(author), 작성 일시(created) 등 여러 데이터를 담을 것이다.
/bbs/model.py 경로에 모델을 정의한다.
처음 model.py 를 확인하면 아래와 같은 내용이며, 모델 정의 시 사용할 models 모듈을 확인할 수 있다.
수정 전
from django.db import models # Create your models here.
Python
Django에서 모델 정의 시, 클래스 형태로 정의하며 models.Model 클래스를 상속하여 사용한다.
모델의 이름은 Board 로 정하였으며, 제목(title), 게시글 내용(content), 작성자(author), 작성 일시(created) 4가지에 대한 데이터를 정의한다.
수정 후
from django.db import models class Board(models.Model): title = models.CharField('제목', max_length=126, null=False) content = models.TextField('내용', null=False) author = models.CharField('작성자', max_length=16, null=False) created = models.DateTimeField('작성일', auto_now_add=True)
Python
model 모듈의 여러 필드를 이용하여, 각 데이터에 적절한 필드로 정의해준다.
😎
공식 문서에 Django Models Fields에 관한 내용이 있다. 역시나 궁금한 사람은 확인해보면 좋다. → Django Models Fields in Django Docs
1.
CharField : SQL에서 varchar 자료형으로 변환되며 글자수 제한있는 문자열 데이터를 저장하는 필드
max_length 인자를 이용하여 최대 글자수를 정의한다.
2.
TextField : SQL에서 text 자료형으로 변환되며 길이 수 제한없는 문자열 데이터를 저장하는 필드
3.
DateTimeField : SQL에서 datetime 자료형으로 변환되며 날짜와 시간이 utc 시간으로 저장하는 필드
auto_now_add 인자를 사용하여 값 미 설정 시, 자동으로 현재 시간을 등록하도록 설정
✍🏻
해당 타임존은 settings.py 에서 변경이 가능하다.

2. 앱 등록과 DB 설정 변경

/toyproject/settings.py 에서 사용할 DB의 설정과 우리가 생성한 게시판 앱(bbs)를 등록해줘야 한다.
1.
bbs 앱 등록
INSTALLED_APPS게시판 앱 이름(bbs)을 추가해준다.
... (생략) # Application definition INSTALLED_APPS = [ 'bbs', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] ... (생략)
Python
2.
DB 설정
만약 sqllite3 를 사용하며, 루트 디렉터리(BASE_DIR) 위치에 존재하는 db.sqlite3 파일(자동 생성)에 데이터를 저장한다면 굳이 건들 필요가 없다.
... (생략) # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent ... (생략) # Database # https://docs.djangoproject.com/en/3.2/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } ... (생략)
Python
😎
공식 문서에 Django Settings DATABASES 에 관한 내용이 있다. 해당 내용에는 sqlite3가 아닌 다른 DB에 연결하는 법을 확인할 수 있다. → Django Settings DATABASES in Django Docs
... (생략) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': '127.0.0.1', 'PORT': '5432', } } ... (생략)
Python
3.
타임존 설정
기본적으로 UTC 시간대를 사용하기 때문에, 이에 관한 설정을 변경해줘야한다.
아무 설정을 변경하지 않은 기본 상태는 다음과 같다.
... (생략) # Internationalization # https://docs.djangoproject.com/en/3.2/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True ... (생략)
Python
USE_TZ 는 False로 변경하여 UTC를 사용하지 않는 옵션으로 변경하고, TIME_ZONE 설정은 한국 시간으로 변경해준다.
... (생략) # Internationalization # https://docs.djangoproject.com/en/3.2/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'Asia/Seoul' USE_I18N = True USE_L10N = True USE_TZ = False ... (생략)
Python

3. 모델 생성 내용 적용하기

manage.py 파일과 makimigrations 를 사용하여 모델의 변경사항을 기록해준다.
실제로 DB에 저장하지는 않으며, 실제 저장을 위해서는 manage.py 파일과 migrate 를 사용해야한다.
만약 모델에 대한 수정 사항 발생 시(생성, 변경, 삭제 등), 아래 두 과정을 순서대로 실행하여 DB에 적용해야 한다.
모델 변경 사항 기록
정상적으로 설정이 되었다면, 아래 이미지와 같이 Create model Board 라는 메세지를 확인할 수 있다.
또한, /bbs/migrations 폴더에 변경사항을 기록한 내용을 확인할 수 있다.
./manage.py makemigrations # 특정 앱 makemigrations ./manage.py makemigrations [app_name]
Bash
변경사항 기록 내용 (0001_initial.py)
모델 변경 사항 기록 확인 후 실제 DB에 저장
정상적으로 DB에 데이터 필드가 설정되었다면, 아래 이미지와 같이 Apply all migrations 라는 메세지를 확인할 수 있다.
⚠️
만약 이미 존재하는 테이블일 때, migrate 명령어로 새로 만들면 에러가 발생한다. 이럴 땐 --fake--initial 옵션을 추가하여 이미 이전에 마이그레이션 한 상태처럼 진행한다.
./manage.py migrate # 특정 앱 migrate ./manage.py migrate [app_name] # 이미 존재하는 테이블로 migrate ./manage.py migrate [app_name] --fake--inital
Bash

⚠️ 잘못된 Migration 복원하기

만약 잘못된 정보로 makemigrations 을 하였을 때 복원하는 방법이다.
1.
이전 마이그레이션 초기화
python manage.py migrate --fake [app_name] zero
Bash
2.
가장 최근의 migrations/xxxx_initial.py 파일 삭제
3.
models.py 수정 후 다시 작업

👁️ 게시판 사이트 만들기 [ VIEW 생성 ]

우리는 위에서 정의한 게시판의 기능에 맞춰 View 를 생성할 것이다.
게시글 리스트 확인, 상세 확인, 게시글 생성, 게시글 수정, 게시글 삭제 총 5가지이다.

1. View 파일 수정

/bbs/view.py 파일에 우리가 원하는 기능의 View를 작성해준다.
아래 파일은 CBV(Class Based View) 즉, 클래스를 기반으로 만들어진 뷰로 만들어주었다.
FBV(Function Based View), 함수를 기반으로 만드는 방법도 있지만 중복 코드 감소 등 CBV가 FBV보다 더 적절하다고 생각했다. (사실 참고한 블로그 분이 CBV 기반으로 작성해주셨다! ㅋㅋㅋ)
😎
물론 CBV가 FBV보다 무조건 좋은건 아니다. 만드는 프로젝트에 따라 더 적합한 방법을 사용하면 된다. 역시 이러한 차이에 대한 궁금증은 잘 정리해주신 분들의 내용을 구글검색으로 쉽게 찾을 수 있다! → CBV vs FBV & 장점과 단점
😎 CBV를 기반으로 작성된 게시글의 View 내용이다.
우선 각 기능에 대해 template의 base.html (아래 과정에서 만들어 줄꺼임) 가 출력되도록 만들어주고, 상세한 기능은 설정하지 않았다.
... (생략) from django.views.generic import TemplateView ... (생략) # 게시글 리스트 확인 페이지에서 사용할 클래스 class BoardListView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context) # 게시글 상세 페이지에서 사용할 클래스 class BoardDetailView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context) # 게시글 생성에서 사용할 클래스 class BoardCreateView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context) def post(self, request, *args, **kwargs): context = {} return self.render_to_response(context) # 게시글 수정에서 사용할 클래스 class BoardUpdateView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context) def post(self, request, *args, **kwargs): context = {} return self.render_to_response(context) # 게시글 삭제에서 사용할 클래스 class BoardDeleteView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context)
Python
아직은 상세 기능이 없어 다 비슷한 내용이니, 이해를 위해 먼저 수정 부분의 코드만 설명하겠다.
... (생략) from django.views.generic import TemplateView ... (생략) # 게시글 수정에서 사용할 클래스 class BoardUpdateView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context) def post(self, request, *args, **kwargs): context = {} return self.render_to_response(context) ... (생략)
Python
TemplateView : 우선 장고에서 기본적으로 제공하는 제네릭 클래스 기반 뷰 중 하나이다. 이 프로젝트에서는 TemplateView 를 사용한다.
제네릭 클래스 기반 뷰는 django.views.generic 모듈에 의해 구현되어 있는 기능 중 하나이다. 장고 프레임워크에 구현되어 있는 기능 사용하는 것으로, 목적에 맞게 원하는 뷰를 골라 사용할 수 있다. → 제너릭 뷰 목록과 상속 내용
template_name : 해당 뷰의 템플릿 페이지 이름을 작성한다. 이 파일은 [app_name]/templates/ 위치에 있어야 한다.
😎
아래 과정에서 templates 폴더를 생성한 후 html 파일을 만들어 줄 것이다. 우선 작성해두자
def get(self, request, *args, **kwargs) : 만약 해당 뷰에서 GET 요청을 받았을 경우 실행되는 함수이다. 지금은 아무 내용이 없지만, return self.render_to_response(context) 메소드를 이용하여 템플릿에 원하는 값을 넘길 수 있다.
render_to_response 는 제네릭 뷰에서 제공하는 함수로 템플릿을 자동적으로 기본 템플릿 엔진을 이용해서 html로 변환해주는 함수이다. 만약 템플릿 내부에서 변수를 사용해야 한다면, 인자로 dict 형태의 데이터를 사용하여 템플릿에서 사용할 수 있다.
def post(self, request, *args, **kwargs) : def get() 경우와 마찬가지 기능이지만, 이름이 post 이기 때문에, POST 요청을 받았을 경우 실행되는 함수이다.

2. url 매핑 파일 수정

/toyproject/urls.py 파일에 View 에서 정의한 기능들에 접속할 수 있도록 url을 정의해준다.
가장 처음 view 파일의 클래스를 import 후, url을 작성한다.
⚠️
상세보기, 게시글 수정, 게시글 삭제 기능게시글의 ID(board_id) 필요하다. 또한, 숫자형(int형)만 인식하도록 <int:~> 형태로 작성한다.
... (생략) # view의 클래스들 import from bbs.views import BoardListView, BoardDetailView, BoardCreateView, BoardUpdateView, BoardDeleteView urlpatterns = [ ... (생략) # url 설정 path('board/', BoardListView.as_view()), path('board/<int:board_id>/', BoardDetailView.as_view()), path('board/create/', BoardCreateView.as_view()), path('board/<int:board_id>/update/', BoardUpdateView.as_view()), path('board/<int:board_id>/delete/', BoardDeleteView.as_view()), ]
Python

3. Templates 폴더에 base.html 만들기

위 과정에서 작성base.html 을 작성할 것 이다.
가장 먼저 /bbs/templates 폴더 속에 존재해야 하기 때문에, templates 폴더를 생성해준다.
templates 폴더에 base.html 파일을 생성하며, 내용은 아래와 같다.
😎
임시 파일이기 때문에 본인 맘대로 해도된다.
<html lang="ko"> <head> <title>base</title> </head> <body> THIS IS BASE PAGE </body> </html>
HTML

4. 테스트를 위해 서버 실행

./manage.py runserver 명령어로 서버를 실행 후 확인해본다.
정상적으로 설정되었다면, 모든 기능에 접속하였을 때 base.html 의 내용이 나올 것이다.
테스트 결과

🔨 게시글 데이터 적용 [ MODEL + VIEW ]

위 과정에서 만든 View에 데이터를 다룰 수 있도록 적용하는 작업이다.

1. 전체 게시글 목록 설정

/toyproject/bbs/views.py 소스코드 중 전체 게시글을 확인할 수 있는 부분을 수정합니다.
수정 전 상태
# 게시글 리스트 확인 페이지에서 사용할 클래스 class BoardListView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context)
Python
수정 후
...(생략) from bbs.models import Board ...(생략) # 게시글 리스트 확인 페이지에서 사용할 클래스 class BoardListView(TemplateView): template_name = 'base.html' # 해당 모델의 전체 데이터 얻어오기 queryset = Board.objects.all() def get(self, request, *args, **kwargs): # dict 자료형 context = { 'view': self.__class__.__name__, 'data': self.queryset } return self.render_to_response(context) class BoardListView(TemplateView): template_name = 'board_list.html' # 최초 1회 queryset = Board.objects.all() def get_object(self, queryset=None): if queryset is None: queryset = self.queryset queryset = Board.objects.all() return queryset def get(self, request, *args, **kwargs): # 해당 모델의 전체 데이터 얻어오기 (접속 시 마다) boards = self.get_object() # dict 자료형 context = { 'boards': boards } return self.render_to_response(context)
Python
변경 부분 설명
~ import Board : 모델에 정의한 Board 모델을 import 한다.
queryset : Board 모델의 전체 데이터(Model.objects.all())를 가져온다.
⚠️
처음 queryset = Board.objects.all() 는 최초 1회만 받아온다. 하지만 get_object() 메소드를 재 정의하여 GET 메소드로 접속 시 DB의 정보를 다시 받아온다.
context { ~ } : 템플릿에 전달 할 변수의 값을 담고 있으며, viewdata 라는 변수를 전달한다.
view : 해당 클래스의 이름 (전체 글 확인 클래스의 경우 BoardListView)
data : queryset 값을 전달 (오브젝트 단위로 통째로 전달)
boards : Board 모델의 전체 데이터( GET 메소드 요청 시 마다 )의 오브젝트 데이터

2. 템플릿에 전체 게시글 출력 테스트

Admin 페이지를 사용하여 이미 Board 모델에 데이터를 하나 넣어둔 상태이다.
만약 Admin 페이지 사용법이 궁금하다면 이 링크를 확인하자.
이전에 테스트를 위해 사용했던 /toyproject/bbs/templates/base.html 파일에 전달받은 context 값을 적용하도록 코드를 변경할 것이다.
수정 전
<html lang="ko"> <head> <title>base</title> </head> <body> THIS IS BASE PAGE </body> </html>
HTML
수정 후
<html lang="ko"> <head> <title>context test base.html</title> </head> <body> view: {{ view }} <br> data: {{ data }} </body> </html>
HTML
변경 부분 설명
{{ view }} : 이전에 response 된 context 변수의 view 값이다. ( context['view'] )
{{ data }} : 이전에 response 된 context 변수의 data 값이다. ( context['data'] )
이제 서버를 다시 실행 후 정상적으로 적용 시, 아래 그림처럼 확인이 가능하다.

3. 게시글 생성 view 변경

<board_id>사용하지 않는 게시글 생성(BoardCreateView 클래스)를 먼저 설명하겠다.
수정 전
# 게시글 생성에서 사용할 클래스 class BoardCreateView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context) def post(self, request, *args, **kwargs): context = {} return self.render_to_response(context)
Python
수정 후
...(생략) from django.http import Http404 from bbs.models import Board ...(생략) # 게시글 생성에서 사용할 클래스 class BoardCreateView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context) def post(self, request, *args, **kwargs): post_data = {key: request.POST.get(key) for key in ('title', 'content', 'author')} for key in post_data: if not post_data[key]: raise Http404('No Data For {}'.format(key)) board = Board.objects.create(title=title, content=content, author=author) context = { 'view': self.__class__.__name__, 'data': board } return self.render_to_response(context) ...(생략)
Python
변경 부분 설명
post_data : request에 담긴 POST 데이터를 dict 형태로 저장한 변수
raise Http404 : 만약 특정 키 값에서 데이터가 존재하지 않은 상태로 POST 요청 시 404 에러
board : Model.objects.create() 함수를 사용하여 저장한다.
Model.objects.create() vs Model() Model.objects.create() : 단일 객체 생성 시 사용하는 메소드 Model() : 모델의 생성자를 사용하여 객체를 생성하며, DB 저장 시 save() 라는 추가 명령어가 필요하다.
정상적으로 설정 되었다면 아래 명령어로 create API를 동작해볼 수 있다.
😎
Insomnia / postman 같은 프로그램을 써도 무방하다.
curl -X POST http://127.0.0.1:8000/board/create/ -d "title='TEST TITLE'&content='TEST CONTENT'&author='TEST AUTHOR'"
Bash
하지만, CSRF verification failed. Request aborted. 라는 메세지와 함께 403 에러가 발생한다.
이는 CSRF 공격 방지를 위한 CSRF Token이 Body에 설정되어 있지 않기 때문이다.
이는 아래 과정의 Template 설정 시 Token을 전달하도록 설정 할 것이기 때문에, 우선 나머지 기능을 구현하자.

4. 게시글의 나머지 기능 구현

이제 <board_id> 를 사용하는 나머지 기능(상세보기, 수정하기, 삭제하기)을 구현한다.
게시글 상세보기 👁️
수정 전
# 게시글 상세 페이지에서 사용할 클래스 class BoardDetailView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context)
Python
수정 후
... (생략) from django.http import Http404 from bbs.models import Board ... (생략) # 게시글 상세 페이지에서 사용할 클래스 class BoardDetailView(TemplateView): template_name = 'base.html' queryset = Board.objects.all() pk_url_kwargs = 'board_id' def get_object(self, queryset=None): if queryset is None: queryset = self.queryset pk = self.kwargs.get(self.pk_url_kwargs) return queryset.filter(pk=pk).first() def get(self, request, *args, **kwargs): board = self.get_object() if not board: raise Http404('invalid board_id') context = { 'view': self.__class__.__name__, 'data': board } return self.render_to_response(context) ... (생략)
Python
변경 부분 설명
queryset : 먼저 Model의 전체 데이터를 받아온 후, queryset.filter() 메소드를 사용하여 원하는 board_id 의 데이터만 사용한다.
게시글 수정하기 ✍🏻
수정 전
# 게시글 수정에서 사용할 클래스 class BoardUpdateView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context) def post(self, request, *args, **kwargs): context = {} return self.render_to_response(context)
Python
수정 후
게시글 추가게시글 상세보기를 섞었다고 생각하면 편하다.
get_object() 메소드 재 정의 + request.POST.get() 메소드를 사용한 POST 전달 데이터 사용
... (생략) from django.http import Http404 from bbs.models import Board ... (생략) # 게시글 수정에서 사용할 클래스 class BoardUpdateView(TemplateView): template_name = 'base.html' queryset = Board.objects.all() pk_url_kwargs = 'board_id' def get_object(self, queryset=None): if queryset is None: queryset = self.queryset pk = self.kwargs.get(self.pk_url_kwargs) return queryset.filter(pk=pk).first() def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context) def post(self, request, *args, **kwargs): post_data = {key: request.POST.get(key) for key in ('title', 'content', 'author')} for key in post_data: if not post_data[key]: raise Http404('No Data For {}'.format(key)) board = self.get_object() if not board: raise Http404('invalid board_id') for key, value in post_data.items(): setattr(board, key, value) board.save() context = { 'view': self.__class__.__name__, 'data': board } return self.render_to_response(context) ... (생략)
Python
변경 부분 설명
post_data : request에 담긴 POST 데이터를 dict 형태로 저장한 변수
raise Http404 : 만약 특정 키 값에서 데이터가 존재하지 않은 상태로 POST 요청 시 404 에러
setattr(board, key, value) : 기존 board 오브젝트의 데이터를 setattr 메소드를 사용하여 새롭게 얻어온 POST 데이터(post_data) 값으로 변경
board.save() : Model.objects.create() 와 같은 명령어로 값을 설정하지 않았기 때문에, 오브젝트의 변경사항을 변경해준다.
게시글 삭제하기 🧹
수정 전
# 게시글 삭제에서 사용할 클래스 class BoardDeleteView(TemplateView): template_name = 'base.html' def get(self, request, *args, **kwargs): context = {} return self.render_to_response(context)
Python
수정 후
게시글 상세보기와 거의 동일하다.
차이점은 게시글 상세보기 기능반환된 Object를 보여주는 것이고, 삭제 기능그 Object를 삭제하는 것이다.
... (생략) from django.http import HttpResponse, HttpResponseRedirect from django.http import Http404 from bbs.models import Board ... (생략) # 게시글 삭제에서 사용할 클래스 class BoardDeleteView(TemplateView): template_name = 'base.html' queryset = Board.objects.all() pk_url_kwargs = 'board_id' def get_object(self, queryset=None): if queryset is None: queryset = self.queryset pk = self.kwargs.get(self.pk_url_kwargs) return queryset.filter(pk=pk).first() def get(self, request, *args, **kwargs): board = self.get_object() if not board: raise Http404('invalid board_id') board.delete() return HttpResponseRedirect("/board/") ... (생략)
Python
변경 사항 설명
board.delete() : URL 에서 입력한 <board_id>를 가진 게시글의 Object 데이터를 삭제한다.
HttpResponseRedirect("/board/") : 삭제 완료 후, /board/ 페이지로 이동한다.

5. 게시글 View 테스트 결과

현재는 CSRF 관련 에러로 인해 완전히 테스트가 어렵기 때문에, 템플릿을 만든 후 테스트 사진을 첨부하겠다.
정상적으로 설정되었을 때 상태를 간략하게 글로 정리하면 아래와 같다.
게시글 수정 기능 : 게시글 생성 기능과 같이 CSRF 관련 에러가 출력되어야한다.
게시글 상세 기능 : 만약 존재하지 않는 <board_id>의 게시글일 경우 404 반환, 존재하는 id라면 해당 게시글의 오브젝트 내용이 나와야한다.
게시글 삭제 기능 : 정상적으로 삭제되며, 다시 게시글 전체 리스트 사이트(/board/ 페이지)로 리다이렉트 되어야 한다.

🛠️ 템플릿을 생성하여 연결하기 [ MODEL + VIEW + TEMPLATE ]

이제 마지막 작업이다. API 로 구현은 끝났으니 웹 사이트 형태로 보기 위해 Template를 만들어 연결해준다.
템플릿도 잘 설계해야 한다. 어떤 영역의 코드가 어떤 데이터를 보여주는지, 실제 눈에 보이는 코드인지 아니면 CSS와 같은 설정 코드인 건지 말이다.
참고한 블로그 에서 템플릿 기본 코드를 잘 작성해주셔서 이 코드를 사용한다.
<html lang="ko"> <head> {% block title %} <!-- 페이지별 타이틀 공간 --> <title>bbs - minitutorial</title> {% endblock title %} {% block meta %} <!-- 페이지별 메타 데이터 공간 --> {% endblock meta %} {% block scripts %} <!-- 페이지별 스크립트 공간 --> {% endblock scripts %} {% block css %} <!-- 페이지별 css --> {% endblock css %} </head> <body> {% block content %} view: {{ view }} <!-- context['view'] --> <br> data: {{ data }} <!-- context['data'] --> {% endblock content %} </body> </html>
HTML
⚠️
이전처럼 base.html 로만 사용하지 않고 각 기능에 맞는 템플릿을 만들고 이름도 바꿀 것이기 때문에 view.py 코드도 수정해줘야 한다.
기능별 템플릿 파일 이름 (/toyproject/bbs/templates/ 내부에 저장)
전체 게시글 확인 : board_list.html
게시글 상세 확인 : board_detail.html
게시글 생성 기능 : board_create.html
게시글 수정 기능 : board_update.html
게시글 삭제 기능 : 미 존재 (기능 완료 후 /board/ 페이지로 리다이렉트)

1. 전체 게시글 확인 템플릿 생성

전체 게시글의 목록을 확인할 수 있는 /templates/board_list.html 파일의 소스이다.
<tbody> 태그에서 템플릿으로 넘어온 boards 변수의 값을 반복문으로 출력한다.
😎
Django의 템플릿에서 반복문을 사용하는 법이 궁금하다면 이 링크의 내용을 보면 도움이 된다.
그 외에 추가적으로 아래 3가지 기능을 적용한다.
1.
BootStrap CSS 적용
2.
행 클릭 시 상세 보기(/board_detail.html/)로 이동
3.
가장 하단에는 새 게시글 작성 버튼 생성
{% extends 'base.html' %} {% block css %} <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> {% endblock css %} {% block title %}<title>게시글 목록</title>{% endblock title %} {% block content %} <table class="table table-hover table-responsive"> <thead> <th>Board ID</th><th>제목</th><th>작성자</th> </thead> <tbody> {% for item in boards %} <tr onclick="location.href='/board/{{ board.pk }}/'"> <td>{{ item.pk }}</td><td>{{ item.title }}</td><td>{{ item.author }}</td> </tr> {% endfor %} </tbody> </table> <a href="/board/create/"><button class="btn btn-primary" type="button">새 게시글 작성</button></a> {% endblock content %}
HTML
view.py 파일에서 해당 기능의 template_name템플릿으로 전송되는 변수의 이름을 변경한다.
...(생략) # 게시글 리스트 확인 페이지에서 사용할 클래스 class BoardListView(TemplateView): template_name = 'board_list.html' # 해당 모델의 전체 데이터 얻어오기 queryset = Board.objects.all() def get(self, request, *args, **kwargs): # dict 자료형 context = { 'boards': self.queryset } return self.render_to_response(context) ...(생략)
Python
정상적으로 설정되었다면 아래 그림처럼 확인할 수 있다.

2. 게시글 상세 확인 템플릿 생성

특정 게시글의 내용을 확인할 수 있는 /templates/board_detail.html 파일의 소스이다.
<table> 태그에서 템플릿으로 넘어온 board 변수의 값을 출력한다.
가장 하단에는 게시글 수정게시글 삭제 버튼을 생성한다.
😎
Django의 템플릿에서 | 문자를 사용하여 필터라는 기능을 사용할 수 있다. → Django 템플릿 필터 기능
{% extends 'base.html' %} {% block title %}<title>게시글 상세 - {{ board.pk }}. {{ board.title }}</title>{% endblock title %} {% block css %} <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> {% endblock css %} {% block content %} <table class="table table-striped table-bordered"> <tr> <th>번호</th> <td>{{ board.pk }}</td> </tr> <tr> <th>제목</th> <td>{{ board.title }}</td> </tr> <tr> <th>내용</th> <td>{{ board.content | linebreaksbr }}</td> </tr> <tr> <th>작성자</th> <td>{{ board.author }}</td> </tr> <tr> <th>작성일</th> <td>{{ board.created | date:"Y-m-d H:i" }}</td> </tr> </table> <a href="/board/{{ board.pk }}/update/"><button class="btn btn-primary" type="button">게시글 수정</button></a> <br><br> <a href="/board/{{ board.pk }}/delete/"><button class="btn btn-primary" type="button">게시글 삭제</button></a> {% endblock content %}
HTML
view.py 파일에서 해당 기능의 template_name템플릿으로 전송되는 변수의 이름을 변경한다.
...(생략) # 게시글 상세 페이지에서 사용할 클래스 class BoardDetailView(TemplateView): template_name = 'board_detail.html' ...(생략) def get(self, request, *args, **kwargs): board = self.get_object() if not board: raise Http404('invalid board_id') context = { 'board': board } return self.render_to_response(context) ...(생략)
Python
정상적으로 설정되었다면 아래 그림처럼 확인할 수 있다.

3. 게시글 생성 기능 템플릿 생성

게시글을 작성할 수 있는 /templates/board_create.html 파일의 소스이다.
이 템플릿은 GET 메소드/board/create/ 페이지에 접속하였을 때 확인 가능한 페이지이다.
{% extends 'base.html' %} {% block title %}<title>게시글 생성</title>{% endblock title %} {% block css %} <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> {% endblock css %} {% block content %} <form action="." method="post" class="form-horizontal"> {% csrf_token %} <table class="table table-striped table-bordered"> <tr> <th>제목</th> <td><input type="text" class="form-control" name="title"></td> </tr> <tr> <th>내용</th> <td><textarea rows="10" class="form-control" name="content"></textarea></td> </tr> <tr> <th>작성자</th> <td><input type="text" class="form-control" name="author"></td> </tr> </table> <button class="btn btn-primary" type="submit">게시글 저장</button> </form> <br> <a href="/board/"><button class="btn btn-primary" type="button">게시글 목록</button></a> {% endblock content %}
HTML
view.py 파일에서 해당 기능의 template_name템플릿으로 전송되는 변수의 이름을 변경한다.
...(생략) # 게시글 생성에서 사용할 클래스 class BoardCreateView(TemplateView): template_name = 'board_create.html' ...(생략) board = Board.objects.create(title=post_data['title'], content=post_data['content'], author=post_data['author']) context = { 'board': board } return self.render_to_response(context) ...(생략)
Python
정상적으로 설정되었다면 아래 그림처럼 확인할 수 있다.

4. 게시글 수정 기능 템플릿 생성

특정 게시글의 내용을 업데이트 할 수 있는 /templates/board_update.html 파일의 소스이다.
{% extends 'base.html' %} {% block title %}<title>{{ board.pk }}번 게시글 수정</title>{% endblock title %} {% block css %} <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> {% endblock css %} {% block content %} <form action="." method="post" class="form-horizontal"> {% csrf_token %} <table class="table table-striped table-bordered"> <tr> <th>Board ID</th> <td><input type="text" class="form-control" name="title" value="{{ board.pk }}" disabled></td> </tr> <tr> <th>제목</th> <td><input type="text" class="form-control" name="title" value="{{ board.title }}"></td> </tr> <tr> <th>내용</th> <td><textarea rows="10" class="form-control" name="content">{{ board.content }}</textarea></td> </tr> <tr> <th>작성자</th> <td><input type="text" class="form-control" name="author" value="{{ board.author }}"></td> </tr> </table> <button class="btn btn-primary" type="submit">게시글 수정</button> </form> <br> <a href="/board/"><button class="btn btn-primary" type="button">게시글 목록</button></a> {% endblock content %}
HTML
view.py 파일에서 해당 기능의 template_name템플릿으로 전송되는 변수의 이름을 변경한다.
...(생략) # 게시글 수정에서 사용할 클래스 class BoardUpdateView(TemplateView): template_name = 'board_update.html' queryset = Board.objects.all() pk_url_kwargs = 'board_id' ...(생략) board.save() context = { 'board': board } return self.render_to_response(context) ...(생략)
Python
정상적으로 설정되었다면 아래 그림처럼 확인할 수 있다.
수정 전
수정 작업
수정 완료

↔️ Django API 서버 만들기

Django에서 템플릿을 사용하여 사이트를 만들 수 있지만, 프론트 엔드에서 사용하기 위한 JSON 값을 반환하는 API 서버로 만드는 경우도 많다.
rest_framework 모듈을 사용하여 이전에 만든 Django 게시판을 API 서버의 형태로 만들것이다.

🏗️ 설치

pip 명령어로 djangorestframework 모듈을 설치해준다.
pip install djangorestframework
Bash

✍🏻 setting.py 변경

INSTALLED_APPS 부분에 rest_framework 를 추가해준다.
... (생략) INSTALLED_APPS = [ ... (생략) 'bbs', 'rest_framework', ] ... (생략)
Python

📦 ModelSerializer 기능 설정

모델의 정보를 JSON 형태로 반환하기 위해 사용하는 기능이다.
내가 get_object() 등의 메소드를 사용하여 Model의 오브젝트를 받아왔을 때, 이를 JSON으로 반환하기 위해 사용된다.
정의한 models.py 와 동일한 위치에 serializers.py 파일을 만든 후 아래와 같이 작성한다.
여기서 모델명은 Board 이며, 본인이 사용하는 모델명으로 바꿔줘야 한다.
또한 fields 값도 본인이 반환받을 필드의 목록을 적어줘야한다.
😎
만약 모든 필드를 전부 반환 받고 싶을 경우 fields = '__all__' 로 작성해주면 된다.
from rest_framework import serializers from .models import Board class BoardSerializer(serializers.ModelSerializer): class Meta: model = Board fields = ('pk', 'title', 'content', 'author', 'created')
Python

🕶️ views.py 수정

이제 views.py 파일에서도 템플릿을 위한 반환 값이 아닌, API 서버의 동작을 위한 JSON 반환 값이 되도록 설정해줘야 한다.
우선 views.py 에서 사용될 모듈 & 모델을 추가해준다.
APIView이전에 사용한 TemplateView와 같이 Django에서 제공하는 뷰의 종류 중 하나이며, API의 결과를 볼 때 사용한다.
# API의 결과를 보여주는 view 클래스 from rest_framework.views import APIView # ModelSerializer 기능 (serializers.py) from .serializers import BoardSerializer # 정의한 모델 from .models import Board
Python
게시글 리스트 확인 부분을 예시로 변경사항을 설명한다.
APIView : 기존의 TemplateView에서 API 결과를 확인하기 위한 뷰로 변경
serializer : serializers.py 에 정의BoardSerializer 기능을 사용하여 데이터를 json 형태로 만들어 반환하며, JSON 값은 serializer.data 로 참조 가능하다.
😎
BoardSerializer 메서드에 사용되는 many 옵션은 반환되는 오브젝트가 여러 개의 값일 때 True로 사용한다. 만약 특정 게시글의 데이터를 반환하는 경우(단일 오브젝트) 일 경우 many 옵션을 사용하지 않는다.
Response : 반환된 json 데이터(serializer.data)와 200 응답 코드를 반환한다.
# 게시글 리스트 확인 페이지에서 사용할 클래스 class BoardListView(APIView): queryset = Board.objects.all() def get_object(self, queryset=None): if queryset is None: queryset = self.queryset queryset = Board.objects.all() return queryset def get(self, request, *args, **kwargs): # 해당 모델의 전체 데이터 얻어오기 boards = self.get_object() serializer = BoardSerializer(boards, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
Python
이제 api로 결과가 반환되는 것을 확인할 수 있다.

🙋🏻‍♂️ APIView 페이지를 원하지 않는 경우

만약 API의 결과를 보여주는 페이지를 원하지 않는 경우, settings.py 에서 추가적인 설정을 해줘야 한다.
...(생략) REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', ) } ...(생략)
Python
해당 설정을 적용하면 아래와 같이 JSON 데이터만 확인 가능하다.

⚙️ Django Admin 페이지 사용법

shell 명령어로 DB를 관리할 수 있지만, Django에서는 관리자 페이지를 별도로 사용이 가능하다.
이 관리자 페이지는 프로젝트에 관한 내용을 관리할 수 있기 때문에, 접근을 위한 별도의 계정을 만들어서 사용한다.
이 사용법에 나오는 예시에서 사용되는 프로젝트, 앱 이름, 모델명과 구조는 아래와 같다.
예시에서 사용되는 정보

👨🏻‍💻 Admin 계정 설정

Admin account 생성

manage.py 파일과 createsuperuser 를 사용하여 어드민 계정을 생성해준다.
어드민 계정으로 사용할 Username, Email, password를 입력받는다.
패스워드 입력 시, 입력 내용이 보이지 않는건 정상이다.
./manage.py createsuperuser
Bash
생성한 계정을 이용하여 관리자 페이지 접근
서버 실행 후, http://127.0.0.1:[port]/admin 에 접속한다.
생성한 Admin 계정의 정보를 입력 후 로그인하면 설정 페이지에 접속할 수 있다.

🏬 Model 관리

Admin 페이지에 Model 등록

일반적으로 바로 접속 시, 우리가 생성했던 bbs앱의 모델을 확인할 수 없다.
이는 모델의 정보를 관리자 페이지에 등록하지 않았기 때문이다.
/bbs/admin.py별도로 등록해야 관리자 페이지에서 모델에 정보를 확인할 수 있다.
초기 상태는 아래와 같다.
from django.contrib import admin # Register your models here.
Python
모델을 import 한 후, admin.site.register([Model 명]) 를 사용하여 admin.py 에 등록해준다.
from django.contrib import admin from .models import Board admin.site.register(Board)
Python
이제 서버를 재시작 후, 다시 접속하면 아래와 같이 모델에 대한 정보를 확인할 수 있다.
더 상세한 Admin 페이지 사용법은 여기서 다루도록 하겠다

😎 그 외 여러 팁

☁️ Django 앱 서버 외부 접속 허용

Django 앱 서버의 기본적인 접속 허용 범위는 로컬뿐이다.
즉 그 상태로 외부(클라우드)에 서비스하면 접속이 불가능하다.
프로젝트의 settings.py 파일에서 ALLOWED_HOSTS 값을 '*' 로 변경한다.
😎
외부에 서버스 하기 때문에, DEBUG 값도 False 으로 변경하는게 좋다.
...(생략) DEBUG = False ALLOWED_HOSTS = ['*'] ...(생략)
Python

✍🏻 참고

글 작성 시 참고 URL 모음
Search
이름
태그
URL
MVT 개념 (2)
Open
블로그
https://velog.io/@inyong_pang/Django-MVTModel-View-Template-%ED%8C%A8%ED%84%B4
MVC vs MVT
Open
국외 자료
https://www.geeksforgeeks.org/difference-between-mvc-and-mvt-design-patterns/
MVC vs MVT (2)
Open
블로그
https://velog.io/@danho-vak/MVC-vs-MVT
django의 특징과 예시 사이트 제작
Open
블로그
https://swarf00.github.io/2018/11/23/get-started.html
django의 특징과 예시 사이트 제작 (2)
Open
인프런
유튜브
https://www.inflearn.com/course/django-%EC%B4%88%EB%B3%B4-%EA%B0%80%EC%9D%B4%EB%93%9C-%EC%8B%A4%EC%8A%B5%EC%9D%84-%ED%86%B5%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-%EC%9E%A5%EA%B3%A0-%EC%9E%85%EB%AC%B8/dashboard
WSGI, ASGI에 대한 정리
Open
블로그
https://blog.neonkid.xyz/249
python 패키지 관련 개념내용
Open
기타
https://wikidocs.net/1418
django 프로젝트 & App 구조
Open
블로그
https://ychae-leah.tistory.com/137
ORM(Object-Relational Mapping) 개념
Open
블로그
https://ychae-leah.tistory.com/134
CBV vs FBV와 장단점
Open
블로그
https://yuda.dev/245
제너릭 뷰 목록과 상속 내용
Open
기타
https://wikidocs.net/9623#_1
Django 템플릿 필터 기능
Open
블로그
https://himanmengit.github.io/django/2018/02/23/Built-In-Template-Filter.html
Django modelserializer DOCS
Open
국외 자료
https://www.django-rest-framework.org/api-guide/serializers/#modelserializer
Model Migration 자료
Open
기타
https://wikidocs.net/9926
COUNT15
TOP