장고 설치
pip install Django
기본적으로 가상환경을 따로 만들고 라이브러리를 설치하는 것이 좋으니 참고!
Django Projcet 생성하기
django 프레임워크를 본격적으로 사용하기 위해서는 django project를 생성해주어야 한다. 터미널 창에 아래와 같은 코드를 입력해보자.
django-admin startproject mysite
코드 입력 후 mysite라는 폴더가 하나 생성된 것을 알 수 있다. 그 안에 진입하면 여러가지 파이썬 파일이 생성된 것을 알 수 있다. 이들은 django 명령어를 터미널에서 쓸 수 있도록 도와주는 파일들이다.
이 중 manage.py 파일을 이용해 설치가 잘 되었는지 확인해보자.
# mysite 폴더로 이동
cd mysite
python manage.py runserver
>>>
October 07, 2024 - 01:24:42
Django version 4.2.16, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
그러면 기본적으로 8000번 포트에 서버가 하나 열리게 된다. 해당 링크로 접속해보자.
위와 같은 글이 나오는 웹페이지가 노출된다. 설치는 제대로 잘 된 것 같다.
Django App 생성하기
Project는 하나의 웹 사이트(프로젝트)라고 생각한다면, App은 각 기능을 구현하는 객체라고 할 수 있다. 하지만 하나의 App은 하나의 프로젝트에만 속해야 하는 것은 아니다. 다른 프로젝트에도 똑같은 기능이 쓰인다면, 똑같은 App을 사용할 수 있다. django app을 생성하는 코드는 아래와 같다.
python manage.py startapp {앱 이름}
나는 'polls'라는 이름의 app을 생성했다. 앱 이름과 같은 폴더가 새로 생성된 것을 알 수 있다. 그리고 db.sqlite3라는 파일도 생성된 것을 알 수 있다.
웹 서버 설정하기
웹 서버는 요청받은 URL에 따른 웹 페이지를 다시 전달해주는 역할을 한다. 웹 서버 상에 해당 URL을 등록해 놓아야 그에 맞는 웹 페이지를 전달해줄 수 있기 때문에, 미리 설정해 줄 필요가 있다.
mysite 폴더 아래에 있는 urls.py를 열어보면, 현재 웹 서버가 가지고 있는 url 패턴을 볼 수 있다.
# mysite/urls.py
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
이 중 2~6줄의 코드를 복사해 방금 만든 app 내에 urls.py라는 파일을 새로 생성해준다.
그리고 각 URL을 자신에 맞게 수정해준다. 기본적으로 해당 코드에 대한 의미는 아래와 같다.
#mysite/polls/urls.py
from django.urls import path
from . import views
# 연결한 URL 모음
urlpatterns = [
# 빈 주소가 요청되면, index라는 이름의 인덱스를 찾아 반환
path('', views.index, name='index'),
# 또는 아래와 같이 index의 name이 아닌 직접 그 함수를 가르킬 수도 있다.
# path('some_url', views.some_url
]
views.py에서 해당 index에 해당하는 함수를 찾아 반환해준다는 의미이다. 다른 파일의 기능을 이용하므로 임포트하는 것을 잊지말자.
그리고 이 URL을 사용하기 위해서는 프로젝트 자체에서도 해당 앱에 대한 URL을 추가해주어야 한다. 다시 mysite의 urls.py로 돌아가자.
# mysite/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
# include: 해당 링크는 include()에 인자로 있는 파일에서 처리
path('polls/', include('polls.urls')
path('admin/', admin.site.urls),
]
include() 메서드를 이용해 'polls/'로 들어오는 요청에 대해서는 polls 폴더 안에 있는 urls.py에서 처리하도록 설정해주었다. 라이브러리 임포트에서 포함해주는 것을 잊지 말자.
이제 앱 폴더 내 views.py에 보여줄 페이지에 대한 설정을 해주자.
# mysite/polls/views.py
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse("Hello world")
아직 HTML 페이지를 따로 준비하진 않았으므로 "Hello world"라는 문구만 있는 페이지를 반환해준다. http 클래스에서 HttpResponse 모듈을 임포트해 구현할 수 있다.
이어서 다시 서버를 열고 '/polls'라는 URL을 뒤에 붙여주면 아래와 같은 페이지가 노출되는 것을 확인할 수 있다.
Django Model 생성하기
모델은 DB를 테이블 별로 읽어서 테이블에 있는 데이터를 코드를 통해 가져올 수 있도록 하는 역할을 한다. 이러한 기능을 ORM이라고도 한다. 앱 폴더 내에 있는 models.py를 수정해 모델을 생성하고, 모델에 필요한 테이블까지 만들어보자.
모델 생성에 앞서 어떤 내용의 모델을 만들지 구상해야한다. 이 글에서는 가을 캠핑지에 대한 설문을 받는 모델을 만들어본다고 가정한다.
1. 모델 생성
# mysite/polls/models.py
from django.db import models
# model 생성
class Question(models.Model):
# 질문을 담을 텍스트 필드
question_text = models.CharField(max_length=200)
# 날짜를 담을 날짜 필드(설문일시 기록용)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
# 어떤 질문에 대한 답인지 알아볼 수 있도록 Question 클래스에서 FK를 받아옴
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
# 답변의 빈도를 세기 위한 정수 필드
votes = models.IntegerField(default=0)
먼저 위 목적에 맞는 클래스를 생성해준다. 설문 질문에 해당하는 Question과 답변에 해당하는 Choice라는 클래스 2개를 생성해주었다.
2. 마이그레이션 생성
생성한 모델에 맞는 테이블을 생성하기 위해서는 마이그레이션을 생성해주어야 한다. 마이그레이션은 설치된 앱에 한해서 생성할 수 있기 때문에, 관련 설정을 해주어야 한다. mysite 폴더 안에 있는 settings.py로 가보자.
# mysite/settings.py
...
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls.apps.PollsConfig' # polls 앱 추가
]
...
settings.py 내 INSTALLED_APPS에 위 코드와 같이 polls 폴더 내 apps.py의 PollsConfig를 전달해주면 설치 세팅이 완료된다. 이제 터미널 명령을 통해 마이그레이션을 생성해주도록 한다.
❯ python manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
마이그레이션을 통해 방금 클래스를 만들어 뒀던 대로 2개의 모델이 생성된 것을 확인할 수 있다. 생성된 마이그레이션을 확인해보기 위해서는 아래와 같은 명령어를 터미널에 입력해주면 된다.
❯ python manage.py sqlmigrate polls 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" bigint NOT NULL REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
앞서 설정한 내용대로 테이블이 생성된 것을 확인할 수 있다. 그러나 내용을 살펴보면 id라는 칼럼이 자동으로 생성된 것을 알 수 있다. 이는 마이그레이션시 자동으로 설정되는 것이다.
그리고 Choice 모델에서는 FK를 사용하기 때문에, question 테이블의 id값에 대한 인덱싱을 항상 할 수 있도록 CREATE INDEX 명령이 추가된 것을 알 수 있다.
3. 테이블 생성
아래 명령어를 통해 마이그레이션 파일을 실행해 실제 테이블을 만들어보자.
❯ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
...
Applying polls.0001_initial... OK
Applying sessions.0001_initial... OK
내용을 살펴보면 polls 이외에도 admin, auth 등에 마이그레이션이 실행되는 것을 볼 수 있는데, 기본값으로 세팅된 앱에 대한 테이블이 같이 생성된 것이다.
Django Model 필드 추가/수정하기
Model에 쓸 수 있는 대표적인 필드 타입들
- BooleanField: T/F 형식을 저장하기 위한 필드
- CharField: 짧은 텍스트를 저장하기 위한 필드
- DateTimeField: 날짜/시간을 저장하기 위한 필드
- FloatField: 실수를 저장하기 위한 필드
- JSONField: JSON 형식을 저장하기 위한 필드
- TextField: 긴 텍스트를 저장하기 위한 필드
https://docs.djangoproject.com/en/5.1/ref/models/fields/
Django 공식 문서를 통해서 더 자세히 알 수 있다.
Model에 필드 추가하기
먼저 필드를 추가할 모델 내용을 수정한다.
# mysite/polls/models.py
from django.db import models
# model 생성
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
# 두 가지 필드 추가
is_something = models.BooleanField(default=False)
average_score = models.FloatField(default=0.0)
그리고 아래 명령어를 통해 마이그레이션을 다시 생성해준다.
❯ python manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0002_question_average_score_question_is_something.py
- Add field average_score to question
- Add field is_something to question
두 가지 필드가 quetion 모델에 추가된다는 내역을 확인할 수 있다.
이제 마이그레이션을 실행시켜보자.
❯ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying polls.0002_question_average_score_question_is_something... OK
0002 버전의 마이그레이션 파일을 실행된 것을 확인할 수 있다.
실제로 테이블에 필드가 추가된 것인지 확인을 위해 DB에 접속해보자. 현재는 sqlite3라는 DB를 사용하고 있기 때문에, 해당 DB로 접속을 해보자.
# sqlite3 터미널로 접속
sqlite3 db.sqlite3
# 테이블 확인
sqlite> .tables
auth_group django_admin_log
auth_group_permissions django_content_type
auth_permission django_migrations
auth_user django_session
auth_user_groups polls_choice
auth_user_user_permissions polls_question
sqlite3 터미널로 접속해 어떤 테이블들이 있는지 확인할 수 있다. 이 중 마이그레이션 내역에 해당하는 django_migrations 테이블을 먼저 확인해보자.
sqlite> SELECT * FROM django_migrations;
1|contenttypes|0001_initial|2024-10-07 02:42:09.534170
2|auth|0001_initial|2024-10-07 02:42:09.563833
3|admin|0001_initial|2024-10-07 02:42:09.589378
4|admin|0002_logentry_remove_auto_add|2024-10-07 02:42:09.613564
5|admin|0003_logentry_add_action_flag_choices|2024-10-07 02:42:09.624832
6|contenttypes|0002_remove_content_type_name|2024-10-07 02:42:09.654547
7|auth|0002_alter_permission_name_max_length|2024-10-07 02:42:09.675276
8|auth|0003_alter_user_email_max_length|2024-10-07 02:42:09.696388
9|auth|0004_alter_user_username_opts|2024-10-07 02:42:09.708276
10|auth|0005_alter_user_last_login_null|2024-10-07 02:42:09.732080
11|auth|0006_require_contenttypes_0002|2024-10-07 02:42:09.739277
12|auth|0007_alter_validators_add_error_messages|2024-10-07 02:42:09.754757
13|auth|0008_alter_user_username_max_length|2024-10-07 02:42:09.775389
14|auth|0009_alter_user_last_name_max_length|2024-10-07 02:42:09.796201
15|auth|0010_alter_group_name_max_length|2024-10-07 02:42:09.815375
16|auth|0011_update_proxy_permissions|2024-10-07 02:42:09.828049
17|auth|0012_alter_user_first_name_max_length|2024-10-07 02:42:09.849206
18|polls|0001_initial|2024-10-07 02:42:09.871596
19|sessions|0001_initial|2024-10-07 02:42:09.896509
20|polls|0002_question_average_score_question_is_something|2024-10-07 03:01:06.714980
0001 버전에 이어 20번째 줄의 0002버전까지 마이그레이션이 실행된 것을 알 수 있다.
이제 필드를 추가한 polls_question의 테이블 구조를 살펴보자. 테이블 구조를 보기 위해서는 .schema 라는 명령어를 이용한다.
sqlite> .schema polls_question
CREATE TABLE IF NOT EXISTS "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL, "average_score" real NOT NULL, "is_something" bool NOT NULL);
위에서 추가했던 is_something과 average_score 필드가 추가된 것을 확인할 수 있다.
특정 마이그레이션 버전으로 롤백하기
만약 특정 마이그레이션 버전으로 테이블을 롤백하고 싶다면, 아래와 같은 명령어를 통해 롤백시킬 수 있다.
# polls 앱의 0001버전으로 되돌리기
❯ python manage.py migrate polls 0001
Operations to perform:
Target specific migration: 0001_initial, from polls
Running migrations:
Rendering model states... DONE
Unapplying polls.0002_question_average_score_question_is_something... OK
해당 앱의 마이그레이션 버전을 입력하면 해당 버전을 기준으로 롤백이 가능하다. 다시 sqlite3로 돌아가 확인해보자.
sqlite> .schema polls_question
CREATE TABLE IF NOT EXISTS "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL);
해당 테이블을 살펴봤을 때, 해당 칼럼이 사라진 것을 확인할 수 있다.
이렇게 롤백했을 때에는 롤백 이후 버전의 마이그레이션 파일과 모델 코드를 다시 되돌려주어야 하는 것을 잊지말아야 한다. 잊은채로 이후 마이그레이션을 실행한다면, 다시 원상복구될 것이기 때문이다
Django Admin 설정
Django Admin에서는 모델에 대한 CRUD 기능을 제공해 더 편하게 모델 및 테이블을 관리할 수 있다. Admin을 사용하기 위해서 기본 설정이 필요하다.
관리자 계정 생성하기
❯ python manage.py createsuperuser
Username (leave blank to use 'minding'): admin
Email address:
Password:
Password (again):
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
위 명령어를 통해 관리자 계정을 생성해준다. (이메일 주소는 적지 않아도 됨) 지금은 학습용으로 생성한 것이라 간단하게 만들었지만, 실제 서비스를 제공하는 프로젝트의 경우 해당 계정은 절대 다른 사람에게 노출되지 않도록 해야 한다.
생성한 뒤 서버를 열어 /admin 이라는 URL을 붙여주면,
위와 같은 페이지가 노출된다.
이 중 Users 메뉴에 들어가면, 이전에 추가한 admin 계정이 노출되는 것을 확인할 수 있다. 오른쪽 상단에 ADD USER 버튼을 통해 새로운 계정을 생성할 수 있다.
Django Admin을 통해 모델 다루기
Admin을 통해서도 모델의 CRUD를 다룰 수 있다. 그러기 위해선 admin에 해당 모델을 등록해야한다. 앱 폴더 내에 있는 admin.py 파일을 열어보자.
from django.contrib import admin
from .models import *
# Register your models here.
admin.site.register(Question)
admin.site.register(Choice)
이전에 만들었던 모델 클래스를 위와 같이 임포트하여 admin에 등록해준다. 저장한 뒤 admin 사이트에 진입해보면,
위와 같이 Question과 Choice가 등록된 것을 알 수 있다. Question에 새로운 레코드를 생성해보자. Questions를 눌러 세부 페이지에 진입해봤다.
오른쪽 ADD Question 버튼을 눌러 새로운 레코드를 추가할 수 있다.
칼럼에 해당하는 값을 적어준 뒤 SAVE를 눌러준다면,
이와 같이 새로운 레코드가 등록된 것을 알 수 있다. 하지만 해당 레코드가 id값으로만 표시되니, 어떤 항목인지 쉽게 알아보기 어렵다. 질문 내용이 노출된다면 더 쉽게 구별할 수 있을 것이다. 이를 위해서는 모델 항목이 표시될 때 어떻게 표시될 것인지에 대한 설정이 필요하다.
# mysite/polls/models.py
from django.db import models
# model 생성
class Question(models.Model):
# 질문을 담을 텍스트 필드
question_text = models.CharField(max_length=200)
# 날짜를 담을 날짜 필드(설문일시 기록용)
pub_date = models.DateTimeField('date published')
# 문자열을 표시할 때 question_text를 반환
def __str__(self):
return self.question_text
...
위 코드와 같이 __str__ 함수를 추가해 문자열을 표시할 때 question_text가 반환되도록 설정하면,
목록에 질문 내용이 표시되는 것을 알 수 있다. __str__ 함수를 수정해 원하는대로 문자열을 표시하게 할 수 있다.
Admin 페이지를 통해서 레코드를 수정/삭제도 가능하다. 해당 레코드를 눌러 상세 페이지에서 수정과 삭제를 진행할 수 있다.
'Minding's Programming > Django' 카테고리의 다른 글
[Django] 폼(Forms) (0) | 2024.10.08 |
---|---|
[Django] 뷰(views)와 템플릿(templates) (0) | 2024.10.08 |
[Django] 모델 메소드(Model Method) (1) | 2024.10.08 |
[Django] 모델 필터링(Model Filtering) (2) | 2024.10.07 |
[Django] Django Shell 사용해보기 (0) | 2024.10.07 |