1. 데이터베이스 설치
mysite/settings.py
를 연다. Django 설정을 변수로 표현한 Python
모듈이다.
- 기본적으로
SQLite
를 사용하도록 구성
- 실제 프로젝트를 시작할 때는
PostgreSQL
과 같은 확장성있는 데이터베이스 사용추천
- 다른 데이터베이스 사용하고싶으면, 데이터베이스 바인딩 설치 후
Settings
값 변경
SQLite
를 데이터베이스로 사용하지 않는 경우, USER
, PASSWORD
, HOST
와 같은 설정이 필요함
다른 데이터베이스를 사용할 경우 이 시점에 데이터베이스를 생성해야함
서버와 현재 지역의 시간을 맞춰주기 위해 TIME_ZONE
을 설정해주는것을 추천
한국으로 설정하는 방법은 위와 같음 ( settings.py
파일에서 TIME_ZONE
항목에 Asia/seoul
로 변경)
시간이 변경된것을 알 수 있음
INSTALLED_APPS
- 현재 Django에서 활성화된 모든 어플리케이션의 이름이 담겨있음
- 기본적으로 프로젝트를 생성하면 존재하는 목록은 아래와 같음
django.contrib.admin
- 관리용 사이트 프레임워크
django.contrib.auth
- 인증 시스템 프레임워크
django.contrib.contenttypes
- 컨텐츠 타입 확인용 프레임워크
django.contrib.sessions
- 세션 프레임워크
django.contrib.messages
- 메세징 프레임워크
django.contrib.staticfile
- 정적 파일을 관리하는 프레임워크
이 앱들중, 사용하기 위해서는 하나 이상의 데이터베이스 테이블을 사용
데이터베이스를 생성해야함
데이터베이스 생성
python manage.py migrate
settings
의 설정과 app 과 함께 제공되는 database migrations에 따라 필요한 데이터베이스 테이블을 생성하게됨
- 위와같이 각 migration이 적용되는 메세지가 뜬 것을 확인 할 수 있음
2. 모델 만들기
모델 = 데이터 저장중인 데이터의 필수 필드 및 동작이 포함됨
Question 모델
- 질문 -
question_text
- 발행일 -
pub_date
Choice 모델
- 질문 -
question
- 선택 텍스트 -
choice_text
- 투표 집계 -
votes
from django.db import models
class Question(models.Model):
#텍스트타입의 필드 생성 최대길이 200
question_text = models.CharField(max_length=200)
#날짜와 시간 타입의 필드 생성, 첫번째 인자를 전달해서 사람이 읽기 좋은 설명을 달 수도 있음
#아래와 같은 경우 date published라는 설명이 달리게 됨
pub_date = models.DateTimeField("date published")
class Choice(models.Model):
#Question 테이블을 외래키로 가진 필드 생성 - 만약 외래키가 삭제되면 영속성을 통해 같은 외래키를 지닌 모든 로우가 삭제됨
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
models.Model
을 상속한 클래스의 변수가 곧 데이터베이스의 필드가 됨
- 즉,
Question
이라는 테이블,Choice
라는 두개의 테이블이 생성됨
- 또한,
ForeignKey
를 통해 테이블간의 관계에 대해 설정할 수 있음. 이 경우Choice
는Question
에 종속적이라고 볼 수 있음
max_length
와 같은경우, 데이터베이스 설정에만 쓰이는게 아니라, 값을 검증할 때에도 쓰인다.
3. 모델의 활성화
장고는 이 코드를 가지고 다음과 같은 일들이 가능함
- 데이터베이스 스키마 생성
Question
과Choice
객체에 접근하기 위한Python
데이터베이스 접근 API 생성
이런 것들을 하기 위해서는 일단 polls
앱을 settings
에 추가해야함
settings.py
INSTALLED_APPS = [
"polls.apps.PollsConfig", # 새로 추가된 app "polls"로도 추가가 됨
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
추가 후
python manage.py makemigrations polls # 이 명령어로 적용할 쿼리문 생성
python manage.py sqlmigrate polls 0001 # 이 명령어로 생성된 쿼리문 출력
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" (
"id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
"id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL,
"question_id" bigint NOT NULL
);
ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_c5b4b260_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
위와 같이 자동으로 쿼리문이 생성된 것을 볼 수 있음
- 테이블의 이름은 자동으로
앱이름_변수이름
이 된것을 볼 수 있음
- 마지막 부분은 Foreignkey를 설정하는 부분임
- 기본 키가 자동으로 추가됨
(id)
- ForeignKey 타입을 설정한 필드명의 경우
question_id
와 같이 뒤에_id
가 붙은것을 볼 수있음
- 마지막으로, 아직 데이터베이스에 이 쿼리문이 적용된것이 아님. migrate명령어를 실행해야 적용됨
python manage.py migrate polls
4. 데이터베이스 가지고 놀기
이제 생성한 데이터베이스를 파이썬을 통해 가지고 놀아볼 수 있음
python manage.py shell #
python 명령어를 입력하는 대신 위 명령어를 사용하는 이유는 이 프로젝트의 가져오기 경로를 사용하기 위해서임
- 가지고 놀 Model 불러오기
- Model에 넣을 값 생성
- 데이터베이스에 적용
- 데이터베이스에 있는 값 수정하기
Model 불러오기
- 모델을 사용하기 위해서는 모델을 불러와야함
- manage.py로 shell을 실행했기때문에 경로는 프로젝트 내에서의 경로로 불러올 수 있음
from polls.models import Choice, Question #import
Model에 있는 모든 값 가져오는 명령어
- 이제 모델을 이용해서 데이터베이스에 있는 값을 다룰 수 있음
- 맨 처음 해볼것은 조회
Question.objects.all() # Question 모델에 있는 모든 값을 보여줘
Out[2]: <QuerySet []> # 아무런 값이 들어있지 않기 때문에 빈 값이 나오게됨
새로운 값 데이터베이스에 집어넣기
- 데이터베이스에 모델의 값을 집어넣음
- 필요한 값은 현재 시간과 질문의 텍스트
# 현재 시간을 가져오기 위해 timezone import
from django.utils import timezone
# 새로운 Question 객체를 생성 timezone의 now() 함수로 현재시간을 pub_date로 넣음
# 아직 데이터베이스에 저장 안됨!
q = Question(question_text = "What's new", pub_date = timezone.now())
# 이 명령어를 통해 데이터베이스에 값을 저장!
q.save()
# 아이디가 자동으로 생성된 것을 볼 수 있음!
q.id
out [3] : 1
위와 같이 값을 생성자를 통해 생성한뒤, 모델객체라면 존재하는 save함수를 통해 데이터베이스에 저장이 가능
수정하기
- 데이터베이스에 이미 저장되어있는 값을 불러와서 수정
# q변수에 방금 데이터베이스에 저장한 객체 할당
q = Question.objects.first()
# 제대로 할당되었는지 확인
q.id
out[19] : 1
# 값을 변경시켜봄
q.question_text = "안녕하세요?"
# 값이 변경되었는지 확인
q.question_text
out[21] "안녕하세요?"
# 다시 데이터베이스에서 값을 조회 - 아직 변경 안된것을 알 수 있음
second = Question.objects.first()
second.question_text
Out[23]: "What's up?"
# 데이터베이스에 값을 저장
q.save()
# 데이터베이스에서 값을 다시 조회
second = Question.objects.first()
second.question_text
Out[23]: "안녕하세요?"
조건을 걸어 조회하기
.filter를 통해 조건을 걸 수 있다.
# 아래와 같이 __로 시작하는 조건비교를 filter lookups 라고 한다.
# 하단 링크로 가면 더 자세한 조건을 볼 수 있다.
Question.objects.filter(question_text__startswith="안녕")
Out[4]: <QuerySet [<Question: 안녕하세요?>]>
https://docs.djangoproject.com/ko/4.2/ref/models/querysets/#field-lookups
“__str__” 함수와 커스텀메소드 추가
from django.db import models
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
class Choice(models.Model):
# ... java의 toString과 같은 함수라고 보면 됨 기본적으로 이 객체가 불릴때 어떤값을 보여줄지 결정
def __str__(self):
return self.choice_text
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
# 지금 시간으로부터 하루 이내의 글인지 체크하는 함수
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
- 사용하기
In [5]: from django.utils import timezone
In [6]: current_year = timezone.now().year
In [7]: current_year
Out[7]: 2023
# 올해 만들어진 설문을 조회
In [8]: Question.objects.get(pub_date__year=current_year)
Out[8]: <Question: 안녕하세요?>
- 값이 없는 경우
In [9]: Question.objects.get(id=2)
---------------------------------------------------------------------------
DoesNotExist Traceback (most recent call last)
Cell In[9], line 1
----> 1 Question.objects.get(id=2)
File ~/anaconda3/envs/py311/lib/python3.11/site-packages/django/db/models/manager.py:87, in BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method(self, *args, **kwargs)
85 @wraps(method)
86 def manager_method(self, *args, **kwargs):
---> 87 return getattr(self.get_queryset(), name)(*args, **kwargs)
File ~/anaconda3/envs/py311/lib/python3.11/site-packages/django/db/models/query.py:637, in QuerySet.get(self, *args, **kwargs)
635 return clone._result_cache[0]
636 if not num:
--> 637 raise self.model.DoesNotExist(
638 "%s matching query does not exist." % self.model._meta.object_name
639 )
640 raise self.model.MultipleObjectsReturned(
641 "get() returned more than one %s -- it returned %s!"
642 % (
(...)
645 )
646 )
DoesNotExist: Question matching query does not exist.
위와 같은 에러 발생
- pk를 통한 조회
# pk를 통해서 조회한다. 장고는 많이쓰는 pk를 숏컷으로 만들었다. pk = 1이라는 문구는
# id=1이라는 문구를 동작시킨다.
In [10]: Question.objects.get(pk=1)
Out[10]: <Question: 안녕하세요?>
- 커스텀 메서드
In [12]: q
Out[12]: <Question: 안녕하세요?>
In [13]: q.was_published_recently
Out[13]: <bound method Question.was_published_recently of <Question: 안녕하세요?>>
In [14]: q.was_published_recently()
Out[14]: True
위와같이 아까 모델에서 작성했던 was_published_recently()메서드를 사용할 수 있는것을 볼 수 있다.
ForeignKey로 관계 지정된 애들 불러오기
질문에는 여러개의 선택지가 있다.
지금 예시로 진행되고 있는 모델은 설문지를 토대로 만들어져있어서, 하나의 질문에 여러개의 선택지가 속해있는 형태이다.
아래와 같이 이 모델을 외래키로 관계지정시켜놓은 모델들을 불러올 수 있다.
q.choice_set.all() # 외래키로 지정한 모델명_set으로 모델들을 볼 수 있다.
Out[18]: <QuerySet []> # 하지만 이 질문에 선택지를 아무것도 안만들어놔서 비어있는 쿼리셋이 반환
_set.create
# _set.create로 이 모델을 외래키로 갖는 모델 생성가능
In [19]: q.choice_set.create(choice_text="안녕함")
Out[19]: <Choice: 안녕함>
In [20]: q.choice_set.create(choice_text="안녕못함")
Out[20]: <Choice: 안녕못함>
# 아래와 같이 두개의 Choice가 생성된 것을 볼 수 있음
In [21]: q.choice_set.all()
Out[21]: <QuerySet [<Choice: 안녕함>, <Choice: 안녕못함>]>
반대로 choice에서 question도 검색가능
In [22]: c = q.choice_set.first()
In [23]: c
Out[23]: <Choice: 안녕함>
In [24]: c.question
Out[24]: <Question: 안녕하세요?>
어드민페이지로 값 조작하기
- 관리자 생성
- 어드민 페이지 접속
- 어드민 페이지에 모델 등록
관리자 생성
python manage.py createsuperuser # 어드민 페이지에 접속 가능한 유저 생성
# 이메일은 필수가 아님
어드민 페이지 접속
http://127.0.0.1/admin 으로 접속하면 로그인 페이지가 뜸
아까 생성했던 아이디와 비밀번호를 입력하면 다음과 같이 뜸
아직 모델을 등록하지 않아서 Question
과 Choice
가 보이지 않음
모델을 어드민페이지에 등록하기
# polls/admin.py
from django.contrib import admin
from .models import Question
admin.site.register(Question)
저장하면 아래와 같은 모습을 볼 수 있음
Questions
로 들어가면 이렇게 보임
우측 상단의 ADD Question
을 통해 질문을 추가할 수 있음
이 서식은 자동으로 Question
모델에서 생성이 됨
물론 수정도 삭제도 가능함
혹시 값을 누가 바꾸었는지 궁금하다면, 수정화면의 우측 상단의 히스토리를 통해 볼 수 있음
위와 같이 수정된 이력을 볼 수 있음
Uploaded by N2T