[Django] 튜토리얼 -1

김가람휘·2022년 2월 9일
0

Django

목록 보기
2/13


장고 튜토리얼

Part 1

설문조사 앱 만들기

  • manage.py가 존재하는 디렉토리에서 polls 디렉토리 생성
  • 이 디렉토리 구조는 설문조사 앱의 집이 되어줄 것입니다.

첫 번째 뷰 작성하기

# polls/views.py
from django.http import HttpResponse

# HttpRequest를 받는다.
def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")
  • 뷰를 호출하려면 이와 연결된 URL이 있어야 하므로 이를 위해 URLconf가 사용됩니다.
# polls/urls.py
# 뷰를 호출하기 위해 연결된 URL
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
#mysite/urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('polls/', include('polls.urls')),
    # 다른 URL 패턴을 포함할 때마다 항상 include()를 사용해야 합니다.
]

  • polls/ 주소에서 index 뷰가 보이게 됩니다.

    path() 인수

    • route : URL 패턴을 가진 문자열입니다.
      ex) https://www.example.com/myapp/ 이 요청된 경우, URLconf 는 오직 myapp/ 부분만 바라 봅니다.
    • view : django에서 일차하는 패턴을 찾으면, HttpRequest 객체를 넘겨주고 view function을 호출합니다.
    • kwargs : 임의의 키워드 인수들은 목표한 view에 딕셔너리형으로 전달됩니다.
    • name : URL에 이름을 지으면, django 어디에서나 명확하게 참조할 수 있습니다.

Part 2

# mysite/settings.py
INSTALLED_APPS = [
'django.contrib.admin', # 관리용 사이트. 곧 사용하게 될 겁니다.
'django.contrib.auth', # 인증 시스템.
'django.contrib.contenttypes', # 컨텐츠 타입을 위한 프레임워크.
'django.contrib.sessions', # 세션 프레임워크.
'django.contrib.messages', # 메세징 프레임워크.
'django.contrib.staticfiles', # 정적 파일을 관리하는 프레임워크
]

모델 만들기

  • 모델 : 부가적인 메타데이터를 가진 데이터베이스의 구조
  • 설문조사 앱에서는 두 가지 모델을 만듭니다.
    • Question, Choice
    • Question에는 질문과 발행일이라는 두 개의 필드가 있습니다.
    • Choice에는 선택 텍스트와 투표 집계라는 두 개의 필드가 있습니다.
# 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') # 날짜와 시간 필드
    # pub_date 필드는 verbose_name으로 'data published'를 넘겨준다.
    # verbose_name : human-readable한 필드 네임, 디폴트는 클래스 안에 정의한 필드 네임


class Choice(models.Model):
	# 각각의 Choice가 하나의 Question에 관계된다.
    # on_delete=models.CASCADE 
    # Choice가 참조하고 있는 Question이 삭제되면 Choice도 삭제
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

모델의 활성화

  • polls 앱이 설치되어 있다는 것을 현재의 프로젝트에 알려야 합니다.
# mysite/settings.py
INSTALLED_APPS = [
    'polls.apps.PollsConfig', # 추가
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

  • makemigrations : 모델을 변경시킨 사실이나 새로운 모델을 만든 변경사항을 migration으로 저장시키고 싶다는 것을 django에게 알려줍니다.
  • migrations : django가 모델에 대한 변경 사항을 저장하는 방법입니다. 이는 디스크 파일입니다.
    polls/migrations/0001_initial.py에서 새 모델에 대한 마이그레이션을 읽을 수 있습니다.
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL,
    "question_id" integer 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;

  • migrate : 아직 적용되지 않은 마이그레이션을 모두 수집해 이를 실행하며 이 과정을 통해 모델에서의 변경 사항들과 데이터베이스의 스키마의 동기화가 이루어집니다.
  • 모델을 변경하는 세 단계 방법을 기억하세요.
    • (models.py 에서) 모델을 변경합니다.
    • python manage.py makemigrations을 통해 이 변경사항에 대한 마이그레이션을 만드세요.
    • python manage.py migrate 명령을 통해 변경사항을 데이터베이스에 적용하세요.

API 가지고 놀기

>>> from polls.models import Choice, Question
# 우리가 만든 모델 클래스 import

# Question의 객체가 아직 없습니다.
>>> Question.objects.all()
<QuerySet []>

# Question을 하나 생성합니다.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

# 객체를 데이터베이스에 저장합니다.
>>> q.save()

# 이제 아이디를 가지고 있습니다.
>>> q.id
1

# 파이썬 속성을 통해서 모델 필드에 접근할 수 있습니다.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# 속성을 바꿈으로써 값을 바꿀 수 있습니다.
>>> q.question_text = "What's up?"
>>> q.save()

# 데이터베이스 안의 모든 Question 객체를 보여줍니다.
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
# polls/models.py
import datetime

from django.db import models
from django.utils import timezone


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __str__(self): # question_text를 받아온다.
        return self.question_text
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)


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
>>> from polls.models import Choice, Question

# __str()__ 추가 기능
>>> Question.objects.all()
# __str()__ 없었을 때 : <QuerySet [<Question: Question object (1)>]>
<QuerySet [<Question: What's up?>]>

# django는 키워드 인수에 의해 전적으로 구동되는 풍부한 데이터베이스 조회 API를 제공합니다.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# 올해 만들어진 question을 가져온다.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# 존재하지 않는 아이디를 요청하면 예외가 발생합니다.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question matching query does not exist.

# django는 기본 키에 대한 정확한 검색을 위한 바로가기를 제공합니다.
>>> Question.objects.get(pk=1)
<Question: What's up?>

# 우리의 커스텀 방식이 효과가 있었는지 확인한다.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# 질문에 몇 가지 선택지를 줍니다.
# create 호출은 새 Choice 개체를 구성하고 INSERT 문을 수행하고
# 사용 가능한 선택 항목 집합에 선택사항을 추가한 다음 새 Choice 개체를 반환합니다.
# django는 API를 통해 접근할 수 있는 ForeignKey 관계의 
# '다른 쪽'을 보유하는 집합을 생성합니다. (question's choice) 
>>> q = Question.objects.get(pk=1)

# 관련 오브젝트 집합에서 선택한 항목을 표시합니다. 지금은 없습니다.
>>> q.choice_set.all()
<QuerySet []>

# 세 개의 choice를 생성합니다.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

# choice 객체는 관련 question 객체애 대한 API 엑세스 권한이 있습니다.
>>> c.question
<Question: What's up?>

# 그 반대도 마찬가지입니다.
# question 객체는 choice 객체에 접근할 수 있습니다.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3

# API는 필요한 만큼 자동으로 관계를 따릅니다.
# 관계를 구분하려면 이중 밑줄을 사용합니다. (__)
# 이 기능은 원하는 수준만큼 작동합니다. 제한은 없습니다.
# pub_date가 올해인 모든 question에 대한 choice 찾기
# (위에서 만든 'current_year' 변수 재사용)
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# choice를 삭제해봅시다.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

관리자 생성하기

개발 서버 시작

$ python manage.py runserver

관리 사이트에서 poll app을 변경가능하도록 만들기

# polls/admin.py
from django.contrib import admin

from .models import Question

admin.site.register(Question)



  • 이 서식은 Question 모델에서 자동으로 생성되었습니다.
  • 각각의 DateTimeField 는 JavaScript 로 작성된 단축 기능과 연결됩니다. 날짜는 《오늘》Today 버튼과 달력 팝업에서 입력할 수 있으며, 시간은 《지금》Now 버튼과 일반적으로 입력하는 시간들을 제공하는 편리한 팝업을 통해서도 입력할 수 있습니다.
  • 저장(SAVE) : 이 유형의 객체에 대한 변경사항을 저장하고, 변경된 목록 페이지를 보여줍니다.
  • 저장 및 편집 계속(Save and continue editing) : 이 객체에 대한 변경사항을 저장하고, 현재 편집창을 갱신합니다
  • 저장 및 다른 이름으로 추가(Save and add another) : 변경사항을 저장하고, 이 유형의 객체에 대한 비어있는 새로운 입력창을 불러옵니다
  • 삭제(Delete) : 삭제를 확인하는 페이지를 띄웁니다.
  • Date published 값을 바꾸고 저장한 후 HISTORY를 확인하면 django 관리사이트를 통해 누가(username) 언제(timestamp) 무엇을 바꾸었는지 목록을 확인할 수 있습니다.

0개의 댓글