본문 바로가기
카테고리 없음

파이썬 - 장고 - 투표하기 공식 튜토리얼 따라하기 #2

지난 게시글에 이은 장고 공식 튜토리얼 투표하기에 대한 따라하기의 다음 편입니다 :)


한국 상황에 맞게 일부 수정한 부분, 그 외 크레이가 나름대로 일부 가감한 부분이 있습니다.

https://itadventure.tistory.com/664

 

파이썬 - 장고 - 투표하기 공식 튜토리얼 따라하기 #1

지난 게시글에서 파이선 장고를 설치, 홈페이지 첫 화면을 구성하는 방법을 살펴보았는데요.https://itadventure.tistory.com/663 파이썬 - 장고, 초간단 웹서버 구축오늘은 윈도우에서 파이썬으로 웹 서

itadventure.tistory.com

https://docs.djangoproject.com/en/5.0/intro/tutorial02/

그럼 시작해볼까요? 렛츠 꼬우~


한글 설정

config/settings.py 파일은 장고와 관련된 여러 설정들이 있는데요.
이 파일에서 다음 내용을 찾아 각각 수정합니다.

     :
LANGUAGE_CODE = 'ko-kr'     # admin 페이지 한국어 적용
TIME_ZONE = 'Asia/Seoul'    # 한국 시간 적용
USE_TZ = False  # 한국 시간 적용
     :

묻지도 따지지도 말고 마이그레이션

장고는 기본적으로 sqlite 라는 데이터 베이스를 사용합니다.
다른 종류의 데이터베이스를 사용하도록 변경할 수 있으나 설정이 조금 더 복잡하므로 최소한 간단하게 성공하는걸 목표로 하겠습니다.
sqlite 데이터 베이스 사용을 위해 마이그레이션(migrate)을 해주어야 하는데요.
터미널 창에 아래와 같이 타이핑하면 마이그레이션이 진행됩니다.

python manage.py migrate

테이블 생성

sqlite 에 데이터를 보관하려면 먼저 테이블을 추가해야 하는데요.
테이블은 일종의 엑셀 시트 1개로 비유하면 적절합니다.

sqlite 에 테이블을 생성하는 방법은 여러가지가 있는데요.
튜토리얼에서는  구조화된 모델 클래스를 정의하고 이를 마이그레이션하는 방법을 사용합니다.
홈페이지 서비스를 진행중 테이블은 계속 구조가 변형될 수 있기 때문에
그러한 변형 과정까지도 다룰 수 있는 방식인데요. PHP 라라벨 프레임워크와도 비슷한 것 같습니다.
먼저 2개의 테이블 구조를 정의하겠습니다.polls/models.py 파일을 열어 아래와 같이 수정합니다.

from django.db import models

# 각각의 클래스가 테이블 구조를 구성
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")
    
    def __str__(self):
        return self.question_text

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

그리고 polls 앱이 존재한다는 사실을 알려주어야 하는데요.

config/settings.py 파일을 열어 INSTALLED_APPS 배열에 아래 내용을 추가합니다. ( 빨강색 부분 )


    :
INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
    :


이제 아래 명령어 2줄을 순차 입력하면 앞에 수식서 'polls_' 가 붙은
polls_question, polls_choice 테이블이 생성됩니다.

python manage.py makemigrations polls
python manage.py migrate

정말 제대로 생성되었나 쉽게 확인하려면 DB Browser for SQLite 윈도우용 프로그램을 사용하면 편리한데요. DB Browser for SQLite 프로그램은 아래 사이트에서 다운받을 수 있습니다.

https://sqlitebrowser.org/

이 프로그램을 다운받아 설치 및 실행 후,
파일 - 데이터 베이스 열기 메뉴를 선택하여 프로젝트 루트 폴더에 있는 db.sqlite3 파일을 열어 보면 되는데요.

여러개의 테이블이 뜨는데 그 중 polls_questionpolls_choice 테이블을 찾아보실 수 있습니다.

테이블 이름을 더블클릭하여 상세한 구조를 확인할 수 있는데요.
어? id 는 클래스에서 정의한 적이 없는데 들어있습니다. id는 보통 인덱스라고 하여 모델 클래스를 구성해 테이블을 생성할 경우 관리를 위해 자동으로 생기는 항목입니다.


장고 인터프리터로 설문지(Polls) 테이블 관리

파이썬은 기본적으로 인터프리터를 지원하는데요.
장고도 인터프리터를 지원합니다.
인터프리터란 파이썬 명령어를 한줄 한줄 실행하며 결과를 볼 수 있는 일종의 장고 전용 터미널입니다.

터미널에서 아래 명령을 입력하면 장고용 인터프리터로 진입합니다.

python manage.py shell

이제 파이썬 명령어를 실행하면 되는데요.
앞의 모델에서 정의한 Choice, Question 모델을 다루기 위해 import 해옵니다.

from polls.models import Choice, Question

그리고 현재 시간을 받아오기 위한 시간 관리 모듈도 import 합니다.

from django.utils import timezone

이제 Question 테이블에 데이터를 입력해 보겠습니다.
아래 2줄을 입력하면 설문 테이블에 설문 제목과 날짜가 1줄 추가됩니다.

q = Question(question_text="새로운 뉴스?", pub_date=timezone.now())
q.save()

인터프리터에서 아래 명령을 실행하면 입력된 데이터를 확인할 수 있는데요.

 Question.objects.all()

이와 같이 출력되는 것은 앞의 모델에서 정의한 __str__ 함수 때문입니다.

    def __str__(self):
        return self.question_text

만약 이 함수를 아래와 같이 정의하면,

    def __str__(self):
        return f"{self.question_text} / {self.pub_date}"

출력결과는 아래와 같습니다. ( 만약 변경된 결과를 보려면 장고 인터프리터를 다시 시작해야 합니다. )

테이블에는 관리를 위한 id 값이 자동 추가된다고 했는데요.

금방 입력한 데이터의 id값을 확인해볼까요?
q.save() 명령 실행 후에야 확인이 가능합니다.

q.id

또한 개별 제목과 날짜도 각각 확인할 수 있습니다.
참고로, 항목 명칭은 모든 이름을 타이핑할 필요 없이 q.que 정도만 타이핑하고 TAB 키를 누르면 나머지 문자가 자동 완성됩니다.

 q.question_text
 q.pub_date

내친 김에 내용을 수정해 보겠습니다.

q.question_text = '무슨 일이야?'
q.save()

 

그리고 다시 전체를 조회해보면 데이터가 변경된 것을 확인할 수 있습니다.

 Question.objects.all()

데이터를 하나 더 추가해 봅시다.

q = Question(question_text='즐겨찾는 간식?', pub_date=timezone.now())
q.save()

다시 전체를 조회해보면 2개의 데이터가 조회되는 것을 확인할 수 있습니다.  

Question.objects.all()

데이터가 아주 많다고 가정한다면 검색 기능을 사용해서 필요한 항목만을 검색하는 것이 좋은데요.
제목이 '무슨'으로 시작하는 설문을 검색한다고 칩시다.

아래 명령을 입력하면, question_text 항목이 '무슨'으로 시작하는 문장의 데이터를 검색해 보여줍니다.

Question.objects.filter(question_text__startswith='무슨')

또한 등록한 날짜의 연도로 검색할 수도 있습니다.
pub_date 항목이 등록일자이기 때문에 아래와 같이 명령어를 입력하면 금년에 등록한 자료만 검색됩니다.

Question.objects.filter(pub_date__year=2024)


설문 항목(Choice) 테이블 관리

이제 설문지에 항목을 추가해보겠습니다.
먼저 설문 테이블의 하나의 설문을 선택한 다음 진행해야 합니다.
공식 튜토리얼은 설문 테이블의 id값이 1인 자료를 탐색하나,
이는 항상 절대적이지 않습니다.
설문 데이터를 2번 추가하여 2번째 설문지에 항목을 추가하거나,
중간에 데이터 삭제 후 새로 추가시 id값은 전혀 다르기 때문입니다.

그래서 아래 명령어를 통해 먼저 id값을 확인해야 합니다.

Question.objects.all().values()
< 결과 >
<QuerySet [{'id': 4, 'question_text': '무슨 일이야?', 'pub_date': datetime.datetime(2024, 5, 6, 8, 23, 23, 732903)}, {'id'
: 5, 'question_text': '즐겨찾는 간식?', 'pub_date': datetime.datetime(2024, 5, 6, 9, 3, 45, 461388)}]>

모두 한줄로 붙여서 표시되기 때문에 보기가 좀 불편합니다.

이번에는 print 문을 사용해 표시해볼까요?
Question 앞에 * 표시가 있다는 점을 유의해 주세요.

print(*Question.objects.all().values(), sep='\n')
< 결과 >
{'id': 4, 'question_text': '무슨 일이야?', 'pub_date': datetime.datetime(2024, 5, 6, 8, 23, 23, 732903)}
{'id': 5, 'question_text': '즐겨찾는 간식?', 'pub_date': datetime.datetime(2024, 5, 6, 9, 3, 45, 461388)}

이제 좀 더 쉽게 알아볼 수 있겠군요.
'무슨 일이야' 설문지의 id값은 여기서는 '4'인것을 보실수 있는데요.
이 값을 확인했으니 get() 명령으로 설문지를 선택해 주면 됩니다.
아래 명령을 입력하되 따라하시는 분께서는 id값을 앞에서 확인한 값으로 넣어주셔야지,
저와 똑같이 하시면 안됩니다,

q = Question.objects.get(id=4)

q를 타이핑하여 확실한지 확인한 다음

q

설문지에 설문 항목(choice)을 추가합니다.

q.choice_set.create(choice_text="부족", votes=0)
q.choice_set.create(choice_text="최상", votes=0)
q.choice_set.create(choice_text="또 해킹하심?", votes=0)

q.choice_set.all() 명령으로 추가한 설문 항목을 확인할 수 있습니다.

q.choice_set.all()

설문 항목 또한 id값이 부여되는데요. 뒤에 .values() 를 붙여 확인할 수 있습니다.
금방 익힌 print 문을 사용하면 아주 깔끔하게 볼 수 있습니다.

print(*q.choice_set.all().values(), sep='\n')
< 결과 >
{'id': 1, 'question_id': 4, 'choice_text': '부족', 'votes': 0}
{'id': 2, 'question_id': 4, 'choice_text': '최상', 'votes': 0}
{'id': 3, 'question_id': 4, 'choice_text': '또 해킹하심?', 'votes': 0}

항목의 갯수를 확인하려면 count()를 붙이면 됩니다.

 q.choice_set.count()
< 결과 >
3

설문 항목을 삭제하려면 delete() 함수를 이용하면 되는데요.
id값을 이용할수도 있지만 이 경우 filter() 함수 이용해  검색 후 검색된 결과를 삭제할 수도 있습니다.

아래는 choice_text 값이 '또'로 시작하는 설문항목을 검색한 후 그 결과를 c 변수에 받아옵니다.

c = q.choice_set.filter(choice_text__startswith='또')

 

c를 타이핑하여 삭제할 자료가 맞는지 확인한 다음,

c

아래 명령을 실행하면 검색한 설문 항목 결과가 삭제됩니다.

c.delete()
 q.choice_set.all()
 
<결과>
<QuerySet [<Choice: 부족>, <Choice: 최상>]>

 

만일 모든 데이터를 이렇게 입력해야 한다면 좀.. 끔찍할 것 같습니다....
DB Browser for SQLite 프로그램도 그리 데이터 입력이 편리한 프로그램이 아닙니다.
좀 더 편하게 입력하는 방법은 없을까요?

장고는 몇가지 세팅을 하는 것으로 데이터를 관리할 수 있는 관리자 페이지를 제공하는데요.
웹 서비스인만큼 아무나 관리자 페이지에 진입하는 것을 방지하기 위해 관리자 아이디부터 만들어야 합니다.


관리자 아이디 생성 및 설정

터미널에서 먼저 관리자 아이디, 비밀번호를 설정해야 합니다.실행중인 장고 인터프리터는 quit 명령을 입력해야 빠져나올 수 있습니다. ( Ctrl+C 안 먹힘 )

quit

아래 명령을 입력하여 관리자 계정을 만들 수 있습니다.

python manage.py createsuperuser

사용자 이름은 admin 을 입력하고 여러분의 이메일 주소와 패스워드를 새로 생각해서 입력해 주시면 됩니다.


관리자 페이지에서 편집하기

설문지 테이블(Question)을 관리자 페이지에서 편집하게 하려면 polls/admin.py 파일을 아래와 같이 수정해야 합니다.

from django.contrib import admin

from .models import Question

admin.site.register(Question)

이제 장고 웹서버를 구동해 보겠습니다.

python manage.py runserver

관리자 페이지에 접속해 볼까요?
관리자 페이지 주소는 http://127.0.0.1:8000/admin 입니다.

방금 전에 생성한 관리자 아이디, 비밀번호로 로그인해봅시다.
와우! 관리자 페이지가 등장하는 것을 확인할 수 있는데요.
POLLS 아래 Questions 테이블이 보이는 것을 확인할 수 있습니다.

Questions 테이블명을 선택하면 데이터들이 나열되는 것을 볼 수 있는데요.
좀 들여다 보면 쉽게 질문 내용을 수정, 삭제, 추가할 수 있는 것을 확인할 수 있습니다.

설문지 제목 클릭시, 편집 화면이 등장,

추가 버튼 클릭시 새로운 설문지 추가 화면 등장.

튜토리얼에는 없지만, Choice 테이블도 관리자 페이지에 넣을 수 있습니다.

polls/admin.py 파일을 아래와 같이 수정 후

from django.contrib import admin

from .models import Question, Choice

admin.site.register(Question)
admin.site.register(Choice)

관리자 페이지에 접속하면, Choices 테이블도 조회되는 것을 볼 수 있는데요.

Question 테이블처럼 목록을 보거나 내용을 편집할 수 있습니다.
아래는 Choice 의 한 설문항목을 편집하는 화면입니다.

수고하셨습니다!
여기까지 한번에 잘 따라하신 분 계시면 정말 잘 하신 거라 칭찬, 칭찬드립니다.

혹시 한번에 잘 안되었더라도 포기하지 않고 몇번 반복해서 시도해 보시면 분면 성공하시리라 믿습니다.

오늘도 방문해주신 모든 분들께 감사드립니다.


말씀 한구절 공유드립니다.

하나님이 죄를 알지도 못하신 이를 우리를 대신하여 죄로 삼으신 것은 
우리로 하여금 그 안에서 하나님의 의가 되게 하려 하심이라
- 고린도후서 5장 21절 말씀 -

'죄를 알지도 못하신 이'는 누구일까요?
모든 성경은 '예수 그리스도'에 대해 증거합니다. 바로 예수님을 지칭하는 것이지요.
그 분 안에 있을 때 우리는 '죄'의 반대인 '의'가 됩니다.


다음 게시글 : https://itadventure.tistory.com/666

 

파이썬 - 장고 - 투표하기 공식 튜토리얼 따라하기 #3

지난 게시글에 이은 장고 공식 튜토리얼 투표하기 따라하기 3편입니다 :)역시 크레이 입맛(?)에 맞게 일부 가감한 부분이 있습니다.지난 게시글 : https://itadventure.tistory.com/665 파이썬 - 장고 - 투

itadventure.tistory.com