Django - 첫 번째 앱 작성하기 part.2

solee·2022년 2월 11일
0

Django

목록 보기
3/12

https://docs.djangoproject.com/ko/4.0/intro/tutorial02/

마저 진행해 보자.

cocacola/cocacola 디렉토리의 settings.py를 열어 수정한다. 상상할 수 있듯이 이 파일은 설정을 저장한다. 데이터베이스는 SQLite가 디폴트인데, 다른 것으로 바꾸고 싶다면 DATABASES에서 ENGINE값과 NAME값을 바꾸고 USER, PASSWORD, HOST를 추가로 설정한 후 데이터베이스 바인딩을 설치해야 한다고 한다. 나는 그냥 SQLite를 사용하겠다.




먼저 timezone을 한국으로 바꾼다. 기존 값 UTC 대신 Asia/Seoul로 설정한 후 USE_TZ을 False로 설정해 준다. timezone을 설정할 때는 나라/도시로 설정해야 한다. 아마 나라가 커서 시간대가 다른 경우들을 위한 거겠지.


다음으로는

python manage.py migrate

migrate 명령어를 실행하는데, 관리용 사이트나 인증 시스템 등 기본 어플리케이션들이 사용할 데이터베이스 테이블을 만들어 주는 것이다. 만약 필요없다면 사용하지 않을 어플리케이션을 삭제하거나 주석처리해도 된다고 한다.

그러기 위해서는 settings.py에서 INSTALLED_APPS을 찾는다. 그러지 않으면 아래에서 모델을 생성한 후에 설정을 추가할 것이다.




모델 생성

이전 글(part.1)에서 django가 models, views, templates를 사용한다고 했다. index view를 생성했고, index polls를 화면으로 띄웠지.

이번에는 모델을 만들 차례다. 모델은 데이터베이스라고 했었다. 아래 코드를 보면 그것이 보인다.
두 모델 Question과 Choice는 polls.models.py에서 정의한다.

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

위의 내용을 추가해준다. Question 클래스의 pub_date에는 models.DateTimeField를 사용해 자료형을 설정해 주는 것이다. CharField나 IntegerField도 동일하다.
또 Choice 클래스에서 외래키를 설정해 주고, cascade를 걸어주는 것도 볼 수 있다.

django는 이 코드를 기반으로 데이터베이스 스키마를 생성한다.




모델 활성화

그 다음으로는 모델을 활성화한다. 아까 말한 settings.py에서 INSTALLED_APPS을 확인해야 하는데, polls/apps.py에 있는 PollsConfig 클래스를 알려줘야 한다.

INSTALLED_APPS = [
    'polls.apps.PollsConfig',
]

이미 수많은 기본 앱들이 있으므로, 이렇게 된다.

이렇게 알려줌으로서 django가 polls앱을 인식하게 된다.
다음으로는 makemigrations 명령어다.

python manage.py makemigrations polls

이런 결과가 출력된다. makemigrations는 모델을 생성 또는 변경했으므로 migration으로 저장하겠다, 즉 모델의 변경사항을 디스크에 저장하겠다는 뜻이다.


무엇이 변경(또는 생성)된 걸까?

sqlmigrate 명령어로 금방 저장한 polls라는 migration이 어떤 SQL을 실행하는지 확인할 수 있다.

python manage.py sqlmigrate polls 0001

결과물을 간단하게 정렬...하려고 해 봤다. 나는 오라클만 해 봤는데 SQLite라 그런지 대충은 알아도 조금 헷갈리는 것들이 있다.
일단 아주 간단하게 읽어 보면,

id, question_text, pub_date라는 컬럼을 가진 polls_question 테이블
id, choice_text, votes, question_id라는 컬럼을 가진 polls_choice 테이블

두 테이블을 생성한다는 것을 알 수 있다.


다시

python manage.py migrate

migrate를 실행하면 아까와 결과가 다르다.
먼저 실행한 migrate 결과:

두 번째로 실행한 migrate 결과:

polls가 추가되어 Running되는 것을 볼 수 있다.




API 실험해보기

docs에서는 가지고 놀기라고 쓰여 있었지만, 나한테는 실험에 가까운 느낌이라 이렇게 적는다. python의 shell을 연다.

python manage.py shell

파이썬 쉘을 열어 아까 작성한 클래스 2개를 import한다. 단순히 import만 한 것이라 객체를 전부 출력하라고 시켜도 아무것도 나오지 않는다.

polls.models에서 Choice와 Question을 import한다.



먼저 Question!

이번에는 timezone을 설정하는데, django는 datetime.datetime.now() 대신 timezone.now() 을 사용하라고 권한다.

이렇게 하면 객체 q에는 두 변수가 저장되는데, 현재 시간과 "What's new?"라는 질문이다.



q.question_text로 값을 출력하고, 덮어씌울 수 있다.

첫 번째 id라서 q다. q가 가지는 id로 q = Question()...해서 다른 값을 또 q.save()하면 q.id는 2가 된다.

이렇게!
그리고 Question.objects.all()을 통해 데이터에 저장된 object (1)과 (2)를 확인할 수 있다. 이 명령어는 데이터베이스에 있는 모든 question을 출력하는 것으로 여기서 question이 삭제되더라도 q.id는 그대로다(auto increment때문에).


그러면 중간에 몇 개가 삭제되고 몇 개가 늘어나면 어떻게 알아볼 수 있을까? polls/models.py로 돌아가 보자.

각 class에 __str__() 메서드가 추가되었다. 각 클래스의 text를 리턴한다. 이렇게 추가된 메서드는 터미널에서도 보기 편하고, django가 기본으로 제공하는 페이지에서도 객체의 표현을 사용하기 때문이라고 한다.


여기에 다른 사용자 지정 메서드를 추가해 보자.

datetime과 timezone을 import해서 얼마나 전에 publish했는지를 출력한다.

shell을 재시작해 보면 이번에는 Question.objects.all()이 다른 결과를 준다!

훨씬 보기 편하다!


filter를 통해 원하는 object만 꺼낼 수도 있다.




아까 만들었던 사용자 지정 메서드인 was_published_recently를 사용하기 위해서는, timezone이 설정되어 있어야 한다.
올해 발행된 질문을 꺼내 오자.

올해 발행된 질문을 꺼내 보는데, 에러가 나는 이유는 아까 내가 다른 q를 만든 덕에 1개 이상의 결과가 나오기 때문이다. get()이 1개의 답만 가질 수 있는 거다.
에러 메시지가 제법 발랄하다....★

제쳐 두고 메서드를 실행해 보면, 다음과 같다.

무사히 실행된다. TRUE! 12월 31일에 만든 메서드를 가지고 1월 1일에 물어보고 싶은 마음이 괜히 생긴다.




이번엔 Choice!

q.choice_set.all()을 실행하면, 아까와 마찬가지로 빈 결과가 나온다.

choice_set을 생성하는데, text는 각각 Not much와 The sky다.

choice_set을 c에 저장하고 c의 question을 꺼내고 q에서 c를 꺼내 보면, API가 연관된 두 객체들 choice_set, Question이 서로에게 접근 가능함을 알 수 있다.




관리자 사이트 접속하기

접속하려면 관리자 사이트가 있어야 한다. 관리 사이트는 django가 제공하므로 그 사이트에 로그인할 superuser를 생성해야 한다.

python을 나가 manage.py가 있는 cocacola 폴더에서 python manage.py createsuperuser를 입력한다.

username과 password를 입력해 관리자 계정을 생성한다. 비밀번호를 마구 쉽게 만들었더니 경고가 뜨는데, 아랑곳하지 않고 y를 눌러 진행한다.




완성했다면 이제 다시 서버를 열어서 대망의 관리자 페이지로 진입할 차례다.

무슨 차이인지는 모르겠지만 unapplied된 문제가 있다고 빨갛게 뜨던 에러가 없다.
그리고 http://127.0.0.1:8080/admin/ 에 진입하면.....

음~ 스윗~

그런데 사이트를 보니 LANGUAGE_CODE를 입력하면 해당 언어로 출력된다고 한다. 다시 settings.py에 가 줄 차례다.

USE_I18N이 반드시 활성화되어야 한다고 한다.

참고로 docs에서는 이렇게 설명하고 있다.

list of language identifiers에서는 이런 것을 찾아볼 수 있었다.

오... 북한? 이러면 또 궁금한 걸 못 참지. 북한으로도 설정해 볼 것이다.

둘 다 해 봤는데 아직은 결과가 같다. 간단한 문장이라서 그런 걸까? 북한이 어떻게 표현하는지 정확히 모르니 비교도 안 된다. 그냥 번역기가 돌아간 거 아닌가 싶기는 한데, 북한 사람들은 이걸 읽으면 무난하게 읽을 수 있을지도 좀 궁금해졌다. 다른 사이트에서 시도해 봐야지.


다시 조국으로 돌아와서 보자. LANGUAGE_CODE 아래로는 저번에 timezone을 설정하면서 바꿔 준 USE_TZ = False도 보인다. 그리고 USE_I18N = True도.

아까의 docs에서 연결되는 '국제화와 현지화' 페이지에서는 이런 설명이 나온다.

처음 튜토리얼을 돌릴 때에 동기한테 도움을 받아 timezone을 설정하면서 뭔지도 모르고 USE_L10N을 적었었는데, 이렇게 보니 로컬라이징에 관한 설정이었던 모양이다. 다만 django 역사의 유감스러운 결과라는 게 참 궁금하다(ㅋㅋ)
일단 갈 길이 바쁘니 다음 단계로 넘어갈까!




polls app 연결하기

그런데 뭔가 이상하지 않은가?

인증 및 권한은 알겠는데, 아까 열심히 만들어서 질문과 선택지를 저장한 polls app이 보이지 않는다!

해야 할 게 더 있다는 뜻이다. polls/admin.py을 수정한다.

맨 윗줄의 import 빼고는 텅 비어있던 polls의 admin에 Questions이라는 관리해줄 사이트를 추가해준 것이다. 그러면 사이트는 이렇게 보인다:

뭐야.. 이건 번역 안 해줘?

Questions을 클릭해 진입해 보면 다음과 같다.

어디... What's new?를 수정해 보자.
클릭해 보면 다음과 같은 페이지가 보인다.

작성 시간 기준 어제 저녁에 작성했던 것이다. 여기서 발행일과 시각을 수정할 수 있다. 터미널에서 수정했던 q.question_text나 q.pub_date도 보인다. 간단하게 What's new new? 로만 수정하고 넘어간다.
히스토리에서는 이렇게 보인다:

이 페이지에서 보여주는 것들은 django와 Question모델이 자동으로 생성하는 것들이다.




이렇게 관리 페이지에서 polls 앱을 확인하고 수정하는 것까지가 part.3이다. 다음 단계에서는 관리가 아니라 투표를 할 수 있는 view를 추가할 것이다.

profile
DA DA DA

0개의 댓글