python Django Practice 2

박상영·2020년 6월 7일
0

모델 만들기

  • Wecode/settings.py
    해당 파일은 현재 Django 인스턴스에서 활성화된 모든 Django application들 의 이름이 담겨있다. app들은 다수의 project에서 사용될 수 있고, 다른 project 에서 쉽게 사용될 수 있도록 패키징하여 배포할 수 있다.

- INSTALLED_APPS 는 Django와 함께 딸려오는 다음의 app들을 포함한다.

  • django.contrib.admin : 관리용 사이트
  • django.contrib.auth : 인증 시스템
  • django.contrib.contenttpyes : content tpye을 위한 framework
  • django.contrib.sessions : session framework
  • django.contrib.messages : messages framework
  • django.contrib.staticfiles : staticfile(정적 파일) 을 관리하는 framework
    이러한 기본 application들중 몇몇은 최소한 하나 이상의 데이터베이스 테이블을 사용하는데, 그러기 위해서는 데이터베이스에서 테이블을 미리 만들 필요가있다.
  • python manage.py migrate
    migrate command는 INSTALLED_APPS 설정을 보고 Website/settings.py 파일의 데이터베이스 설정 및 app과 함께 제공된 "database migration"에 따라 필요한 데이터베이스 테이블을 만든다.

모델 만들기

  • polls/models.py

여기에서 각 model은 django.db.models의 class를 뒷받침 해주는 class로 표시됩니다. 각 모델에는 여러 class 변수가 있으며 각 변수는 모델의 database field를 나타낸다.

  • database 의 각 field

class Field 의 인스턴스로서 표현됩니다.
CharField는 string field를 표현하여 question_textchoice_text 에 필수인수(mat_length) 200을 입력해주었다.

  • DateTimeField
    날짜와 시간(datetime)을 필드로 표현합니다. 각 field가 date published 자료형을 가지도록 해주었다.
  • 선택적 인수
    Field는 다양한 선택적 인수들을 가지는데, 여기서는
    default로 하여금 votes의 기본값을 0 으로 설정

각각의 Field 인스턴스의 이름(question_text 또는 pub_date) 은 기계가 읽기 좋은 형식(machine-friendly format) 의 database field 의 이름입니다. 이 인스턴스의 이름은 database에서 column명 으로 사용할 것이다.

  • ForeignKey
    각각의 Choice 가 하나의 Question 에 관계된다는 것을 Django 에게 알려줍니다. Django 는 다-대-일(many-to-one), 다-대-다(many-to-many), 일-대-일(one-to-one) 과 같은 모든 일반 데이터베이스의 관계들를 지원합니다.

모델의 활성화

모델에 대한 이 작은 코드가, Django에게는 상당한 양의 정보를 전달합니다.

  • 이 앱을 위한 데이터베이스 스키마 생성(CREATE TABLE 문)
  • Question과 Choice 객체에 접근하기 위한 Python 데이터베이스 접근 API를 생성
    하지만 가장 먼저 현재 project에 polls 앱이 설치되있다는 것을 알려야 한다.

앱을 현재의 프로젝트에 포함시키기 위해서는, 앱의 구성 클래스에 대한 참조를 INSTALLED_APPS 설정에 추가해야 합니다. PollsConfig 클래스는 polls/apps.py 파일 내에 존재합니다. 따라서, 점으로 구분된 경로는 polls.apps.PollsConfig가 됩니다. 이 점으로 구분된 경로를, Wecode/settings.py 파일을 편집하여 INSTALLED_APPS 설정에 추가하면 됩니다.


이제 Django는 polls앱이 포함된 것을 알게되었다.

$ python manage.py makemigrations polls command 입력

makemigrations 을 실행시킴으로서, 당신이 모델을 변경시킨 사실과(지금의 경우는 새로운 모델을 만들었다.) 이 변경사항을 migration으로 저장시키고 싶다는 것을 Django에게 알려줍니다.

$ python manage.py sqlmigrate polls 0001

sqlmigrate command는 migration 이름을 인수로 받아, 실행하는 SQL 문장을 보여줍니다.

  • table 이름은 app 의 이름과 model의 이름(lower) 이 조합되어 자동으로 생성된다. app의 이름인polls 와 lower()로 표기된 모델의 이름인 question 과 choice 가 합쳐집니다.(이 동작을 override(재지정) 하여 수정할수있다.
  • 기본 key(id) 가 자동으로 추가(override 가능)
  • 관례에 따라 Django는 ForeignKey의 필드명에 "_id"이름을 자동으로 추가(override 가능)

ForeginKey

class ForeignKey(to, on_delete, **options)

다대일 관계이고 두 가지 위치 인수가 필요합니다. model이 관련된 클래스와 on_delete 옵션이다. 재귀 관계를 만들기 위해서는(자신과 다대일 관계가 있는 객체)model.ForeignKey("self", on_delete=models.CASCADE)를 사용한다.

ForeignKey.on_delete

user = models.ForeginKey(
    Users,
    models.SET_NULL,
    blank = True,
    null = True,
)

ForeignKey 로 참조된 객체가 삭제될 때, Django는 on_delete 인수에 정의된 SQL 제약 조건의 동작을 에뮬레이션 한다. Null이 허용된 ForeignKey가 있고 참조된 객체가 삭제될 때 null 세팅하기 원할경우 위에있는 형식이 된다.

  • foreign key 관계는 FOREIGN KEY 제약 조건에 의해 명시된다.
  • 사용하는 데이터베이스에 따라, 데이터베이스 고유의 필드타입이 조정됩니다. 따라서, 자동 증가 필드를 생성할 경우 auto_increment(MySQL), serial(PostgreSQL), integer primary key autoincrement(SQLite)와 같이 사용하는 데이터베이스에 따라 적절한 필드타입이 자동으로 선택됩니다. 필드 명에 사용되는 인용부호도 상황에 따라 겹따옴표나 홑따옴표가 적절히 선택됩니다.
  • sqlmigrate command는 실제로 database에서 migration을 실행하지 않습니다. 대신 SQL Django가 필요 하다고 생각하는 것을 볼수있도록 화면에 출력한다.
    Django가 수행 할 작업을 확인 또는 변경을 위해 SQL Script 가 필요한 database 관리자가 있는지 확인하는데 유용하다.

tip: python manage.py check command를 통해 migration 을 수행하거나 database를 건드리지 않고도 project의 문제를 확인할수있다.

$ python manage.py migrate command 입력

migrate 명령은 아직 적용되지 않은 마이그레이션을 모두 수집해 이를 실행하며(Django는 django_migrations 테이블을 두어 마이그레이션 적용 여부를 추적합니다) 이 과정을 통해 모델에서의 변경 사항들과 데이터베이스의 스키마의 동기화가 이루어집니다

  • migration 은 매우 기능이 강력하여, 마치 project 를 개발할 때 처럼 database나 tabl에 손대지 않고도 model의 반복적인 변경을 가능하게 해준다.

model의 변경을 만드는 세단계

  • models.py에서 model을 변경
  • python manage.py makemigrations를 통해 이 변경사항에 대한 migration을 만든다.
  • python manage.py mirate command를 통해 변경사항을 데이터베이스에 적용

API!!

Python shell로 Django API를 만져본다.
$ python manage.py shell command
단순히 python 이라고 실행 하는대신 manage.py shell 이 붙어있는 이유는 manage.py 에 설정된 DJANGO_SETTINGS_MODULE 환경변수 때문이다.
이 환경변수는 Wecode/settings.py 파일에 대한 Python import path를 Django에 제공하여, Python shell에서 Django가 접근할 수 있는 Python module path 를 그대로 사용 할 수 있다.

Django에서 동작하는 모든 명령을 Python shell에서 그대로 시험해 볼 수 있다.

from polls.models import Choice, Question
## 작성한 polls/models.py 에서 class Choice와 Question을 import 한다.


## 아직 시스템에 questions 가 없다.
>>> Question.objects.all()
<QuerySet []>

# 새로운 Question을 만든다.
# 표준 설정 파일에서 표준 시간대 지원이 활성화되어 있으므로 Djangosms pub_date 에 tzinfo 를 사용하여 날짜 시간을 예상한다.
# Timezone.now()를 사용한다.
# Python 의 datetime.datetime 객체에는 시간대 정보를 저장하는 데 사용할 수 있는 tzinfo 속성이 있으며 datetime.tzinfo의 하위 클래스 인스턴스로 표시된다.


>>> from django.utils import timezone
>>> q = Question(question_text = "What's new?", pub_date = timezone.now()
>>>q.save()
# obeject를 database에 저장하려면 .save()를 명시적으로 호출해야 한다.
>>>q.id
(출력값) 1
# .save()를 호출하지않고 id를 출력하면 아무것도 출력되지않는다. 하지만 호출하여 저장하면 1 이라는 ID값을 가지고있는것을 볼수있다.

>>> q.question_text
# 위에 class Question에 question_text 는 "What's new?"라는 값을 저장했기때문에 "What's new? 가 출력이된다.

>>> q.pub_date
# pub_date 는 datetime.datetime.now() 와 같은 timezone.now()를 저장했고
# 출력은 
datetime.datetime(2020, 6, 7, 9, 42, 32, 936058, tzinfo=<UTC>)  datetime과 같은값이 나온다.
    

>>> q.question_text = "What's up?"
# 다시 q.question_text에 "What's up?" 을 새로 입력해준뒤 .save()를 호출하여 저장한다.
>>> q.save()

# objects.all()은 database의 모든 question을 출력한다.
>>> Question.objects.all()
# <QuerySet [<Question: Question object (1)>]>

위의 <QuerySet [<Question: Question object (1)>]>은 이 객체를 표현하는데 별로다 Question model을 수정하여 __str__()method 를 Question과 Choice에 추가해준다.

models.py에 __str__() method를 추가하는것은 객체의 표현을 대화식 prompt에서 편하게 보려는 이유 말고도, Django가 자동으로 생성하는 관리 사이트 에서도 객체의 표현이 사용되기 때문이다.

이번엔 custom method 도 추가해보자.

import datetime 은 python 의 표준 모듈은 datetime 모듈을
from django.utils import timezone 은 Django의 시간대 관련 유틸리티인 django.utils.timezone을 참조하기 위해 추가했다.

추가했으니 다시한번 shell에서 실행해본다.

>>> from polls.models import Question, Choice

# __str__() method를 추가했으니 동작하는지 확인해본다.
>>> Question.objects.all()
<QuerySet [<Question: What`s up?>]>

# Django는Keyword arguments에 의해 구동되는 database 조회 API를 제공한다.
>>> Question.objects.filter(id=1)
id의 1에 해당하는 객체 출력
<QuerySet [<Question: What`s up?>]>

>>> Question.objects.filter(question_text__startswith = "What")
# 질문에서 What으로 시작하는 객체 출력
<QuerySet [<Question: What`s up?>]>

# 올해 질문된 질문을 출력할수도있다.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
# 현재기준으로 년도를 받는다.(2020)
>>> Question.objects.get(pub_date__year = current_year)
# pub_date__year 또한 2020이기떄문에 출력은 같다.
<Question: What`s up?>

# 존재하지않은 id를 입력하면 error가 발생한다.
>>> Question.objects.get(id=2)
# polls.models.Question.DoesNotExist: Question matching query does not exist.

관리자 사이트

먼저 관리자 생성을 합니다 $ python manage.py createsuperuser
Username: admin
Email address: admin@example.com
Password: ******** len(Password) > 7
이렇게 초기설정으로 superuser를 생성합니다.

로컬도메인의 /admin/ 으로 이동(http://127.0.0.1:8000/admin/)
하지만 들어가게되면 아직 poll app이 보이지않는다. register등록을 해줘야된다.

profile
backend

0개의 댓글