1) Python 가상 환경 생성 및 활성화
py -m venv project-name
project-name\Scripts\activate.bat
#다시 비활성화를 원할 시 명령어 실행
deactivate
2) 새로운 Django 프로젝트 생성
django-admin startproject project-name
3) manage.py
Terminal
에서 조작할 수 있는 명령을 제공한다.python manage.py runserver
포트 번호
가 뜨게 되고 브라우저에서 해당 포트로 접속하면 Django
의 default 페이지
가 뜨게 된다.Django
의 default 페이지
)App
을 생성해 보자.python manage.py startapp app-name
웹페이지주소/RequestURL
를 하면 GET method
를 통해 Request URL을 찾아 해당하는 APP을 보여 준다.1) mysite(프로젝트 메인) urls.py에서 app 호출
urls.py
에서 url
을 만들 수 있다.#mysite의 urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('polls/', include('polls.urls')), #만약 polls라는 requestURL을 받으면 polls.urls에서 처리해 주도록 전달
path('admin/', admin.site.urls),
]
2) polls(호출한 app) urls.py에서 url 경로 설정
APP
을 생성할 것이기 때문에 생성된 App
에 urls.py
를 생성해 url 패턴
을 만들어 준다.#polls(app-name)의 urls.py
from django.urls import path
from . import views #views가 선언되지 않으면 오류가 남
urlpatterns = [
path('', views.index, name='index'), #만약 requestURL이 없으면 views의 index에 간다.
]
3) polls(호출한 app) views.py에 url 호출 시 보여 줄 화면 구현
polls
라는 새로 만든 app
의 views.py
의 index
에 단순한 코드를 넣어 준다.from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, World.")
Hello, World
가 표출되는 것을 알 수 있다. models.py
DB를 테이블별로 읽어서 하나의 테이블에 저장된 값을 코드에서 읽을 수 있게 도와준다.orm
이라고도 부른다.모델
을 생성해 보자. 1) 사용할 model
을 model.py
생성
#model은 models.Model을 상속받아야 한다.
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length = 200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
#Question의 unique id 저장
question = models.ForeignKey(Question, on_delete = models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.InterField(default=0)
2) setting.py
의 INSTALLED_APPS
추가
setting.py
에서 INSTALLED_APPS
는 APP
을 정의하는 곳이다.app
을 추가해 주는데 만든 APP(polls)
의 apps.py
에 있는 config
클래스 이름을 추가해 주면 된다.INSTALLED_APPS = [
'polls.apps.PollsConfig', #추가한 app
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
3) 만든 model
을 migration
하기
model
을 migration
하기 위해 다시 Terminal
로 가 명령어를 입력해 준다. 이 명령어는 모델의 변경 사항
을 담고 있는 마이그레이션 파일을 생성
하는 명령어이다.python manage.py makemigrations app_name
models.py
에 만들어 둔 두 개의 class
가 model
로 생성되었음을 알 수 있다.테이블 구조
를 직접 보기 위해서는 다음과 같은 명령어를 입력해 준다.python manage.py sqlmigrate polls 0001
마이그레이션을 실행
해 변경된 내용을 데이터베이스에 적용
하는 명령어는 다음과 같다. 이 단계까지 거치면 최종적으로 Django
에 테이블이 생성된 것이다.python manage.py migrate
Django
의 Field 타입은 공식 문서에서 확인할 수 있다.CharField
, DateField
, TextField
등이 있다. (각자 데이터 타입
을 적용할 때.)models.py
중 field
를 추가할 모델에 추가 class Question(models.Model):
question_text = models.CharField(max_length = 200)
pub_date = models.DateTimeField('date published')
is_something = models.BooleanField(default=False) #boolean 타입의 field를 추가했다.
average_score = models.FloatField(default=0.0) #float 타입의 field를 추가했다.
2) field
를 모델에 반영하기 위해 migration
하기
models.py
를 수정 후 이를 실제 모델에 반영하기 위해서는 4에서 진행한 방식과 동일하게 migration
해 주어야 한다.python manage.py makemigrations #변경 사항 확인
python manage.py migrate #변경 사항 DB 반영
sqlite3(Django에서 제공하는 SQL 환경)
에 접속한다.sqlite3 db.sqlite3
명령어를 입력해 준다..tables
를 하면 다음과 같이 현재 프로젝트의 DB
에 생성된 TABLE
을 확인할 수 있다. ;
을 사용해 쿼리문을 종료해 준다.테이블의 구조
를 보기를 원한다면 .schema table명
을 입력해 준다.SQL 종료
를 위해서는 ctrl+C
를 해 주면 된다.migration 파일
과 models.py
도 바꾸어 주어야 한다.)python manage.py migrate polls 0001 #polls의 상태를 0001의 초기 상태로 돌려준다
1) admin 계정 만들기
admin 계정
은 superuser
계정이기 때문에 사용자에게 부여되면 안 된다.python manage.py createsuperuser #admin (superuser 계정을 만든다)
2) django server
에 접속하여 로그인
Django에서 부여된 포트
/admin을 하면 로그인 창이 나오게 된다.User
에서 특정 user
들을 만들어 줄 수 있고 superuser
를 추가할 수도 있다. 그 유저들은 admin 화면에서 로그인 가능하다.Django admin
에 model
들도 등록해서 쉽게 admin
에서 등록할 수 있는 방법은 없을까. 1) admin.py
에 모델을 등록
from .models import *
# Register your models here.
admin.site.register(Question) #admin 사이트에 Question 모델을 등록한다
2) admin에 접속해 확인
add
를 눌러 데이터
를 추가할 수 있다. (테이블 구조
를 바꿀 수 있는 게 아니라 데이터
를 넣을 수 있는 것이다.)3) admin에서 데이터 등록
add
선택 시 테이블 구조
에 맞는 데이터 값을 입력할 수 있는 창이 나온다. 데이터
들은 다음과 같이 뜨는데 Question을 대표적으로 어떻게 표시해 줄 것인지에 대해서는 models.py
를 통해 수정할 수 있다. models.py
를 수정해 준다. def __str__(self)
를 통해 수정될 값을 변경해 줄 수 있다.class Question(models.Model):
question_text = models.CharField(max_length = 200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return f'제목: {self.question_text}, 날짜: {self.pub_date}'
python manage.py shell
명령어를 통해 shell에 접속할 수 있다.Django Shell
에서 모델을 쓰고 싶을 시에는 따로 import를 해 주어야 함. (Django shell
은 전체 프로젝트
를 관점으로 실행되기 때문에)object
의 데이터
를 읽어오길 바랄 때는 model.objects.all()
을 입력한다.Question,Choice 오브젝트
가져오려면 .object.all()
을 사용한다.Question.objects.all()
Choice.objects.all()
Choice
의 첫 번째 데이터를 변수에 담는다.choice = Choice.objects.all()[0]
choice.id
choice.choice_text
choice.votes
Choice
는 models.py
에서 question
이 정의되어 있어 호출만 하면 가지고 올 수 있다. (ForeignKey로 관계를 맺고 있기 때문에.)choice.question
choice.question.pub_date
choice.question.id
Question
에서는 models.py
에 choice
를 가지고 올 수 있는 요소가 없다. 그렇기 때문에 choice_set
을 사용해서 확인해 준다.question.choice_set.all()
Django
에서는 timezone
을 사용해서 시간을 구한다. datetime
과 출력 값을 보면 다르다는 것을 알 수 있다.from datetime import datetime
datetime.now()
#output: datetime.datetime(2023, 4, 25, 2, 52, 9, 115630)
from django.utils import timezone
timezone.now()
#output: datetime.datetime(2023, 4, 24, 17, 52, 24, 443460, tzinfo=datetime.timezone.utc)
1) 데이터 생성
q1 = Question(question_text = "커피 vs 녹차")
q1.pub_date = timezone.now() #현재 시간을 저장해 준 후
q1.save() #DB에 반영
DateTime default 값 설정
auto_now = true
를 하면 데이터가 저장될 때마다 현재 시간이 저장된다.auto_now_add = True
를 하면 데이터가 처음 추가될 때 현재 시간이 저장된다.
2) 연결된 테이블의 데이터 추가하기
q3.choice_set.create(choice_text = "b") #set을 연결하여 추가할 수 있음 (create 메소드 활용)
choice_c = Choice(choice_text='c', question=q3) #Choice 변수를 그대로 추가할 수도 있음 (question이라는 key값으로 연결)
choice_c.save()
3) 데이터 변경하기
q = Question.objects.last() #Question에 저장된 데이터 중 가장 마지막 데이터를 조회 후 변수에 담는다
q.question_text = q.question_text + '???' #변수에 내용을 더해 수정한다.
4) 데이터 삭제하기
choice = Question.objects.last()
choice.delete() #데이터를 삭제한다
1) get
을 이용한 필터링
get
은 데이터가 하나인 경우나 아예 존재하지 않는 경우에 대해 오류가 발생한다는 사실을 인지하고 사용해야 한다.polls.models.Question.DoesNotExist: Question matching query does not exist.
다음과 같은 오류가 발생한다.polls.models.Question.MultipleObjectsReturned: get() returned more than one Question -- it returned 2!
다음과 같은 오류가 발생한다.Question.objects.get(id=1)
q = Question.objects.get(question_text__startswith='녹차') #녹차가 들어오는 질문을 가지고 온다
Question.objects.get(pub_date__year=2023) #2023년에 저장된 데이터를 가지고 온다
2) filter
를 이용한 필터링
filter
를 사용한다면 아예 존재하지 않는 경우나 여러 개의 데이터가 찾아지는 경우도 QuerySet
을 통해 표출된다.Question.objects.filter(question_text__startswith='가장')
#output: <QuerySet [<Question: 제목: 가장 좋아하는 계절은?, 날짜: 2023-04-24 17:16:45+00:00>, <Question: 제목: 가장 좋아하는 디저트는?, 날짜: 2023-04-24 17:16:58+00:00>]>
3) QuerySet
의 SQL 쿼리
보기
QuerySet
으로 나오는 output값에 .query
를 이용해 SQL 쿼리
를 보여 줄 수 있다.print(Question.objects.filter(question_text__startswith='가장').query)
#output: SELECT "polls_question"."id", "polls_question"."question_text", "polls_question"."pub_date" FROM "polls_question" WHERE "polls_question"."question_text" LIKE 가장% ESCAPE '\'
Question
에서 choice_set으로 가면QuerySet
이지만Choice
에서 question으로 갈 때는Choice
에는하나의 question만 존재
하기 때문에하나의 question
만 나온다.여러 개
일 때만QuerySet
이 주어진다.
4) contains() 연산자
활용해서 필터링 하기
Question.objects.filter(question_text__contains='휴가')
5) gt()
이용해서 필터링 하기
gt()
보다 클 때 조회하는 연산자이다.Choice.objects.filter(votes__gt=0).query
print(Choice.objects.filter(votes__gt=0).query)
#output: SELECT "polls_choice"."id", "polls_choice"."question_id", "polls_choice"."choice_text", "polls_choice"."votes" FROM "polls_choice" WHERE "polls_choice"."votes" > 0
#그래서 query문으로 빼면 where절에 votes > 0가 나오게 된다.
6) 정규표현식
을 사용해 필터링 하기
Question.objects.filter(question_text__regex=r'^휴가.*어디')
print(Question.objects.filter(question_text__regex=r'^휴가.*어디').query)
#output: SELECT "polls_question"."id", "polls_question"."question_text", "polls_question"."pub_date", "polls_question"."owner_id" FROM "polls_question" WHERE "polls_question"."question_text" REGEXP ^휴가.*어디
#정규표현식을 사용할 수도 있다. 정규표현식을 사용하는 경우 where절에 정규표현식이 포함된 쿼리문이 나오게 된다.
7) 모델 관계 기반
의 필터링 하기
filters(table명__column명__조건)
을 이용해 필터를 해 준다.print(Choice.objects.filter(question__question_text__startswith='가장').query)
#output: SELECT "polls_choice"."id", "polls_choice"."question_id", "polls_choice"."choice_text", "polls_choice"."votes" FROM "polls_choice" INNER JOIN "polls_question" ON ("polls_choice"."question_id" = "polls_question"."id") WHERE "polls_question"."question_text" LIKE 가장% ESCAPE '\'
** 8) exclude()
를 이용해 필터링 하기
exclude()
를 사용하면 조건에 해당되는 내용이 제외된 상태로 필터링이 된다.Question.objects.exclude(question_text__startswith='휴가') #휴가로 시작하는 질문만 제외하고 조회
반복적으로 사용
하는 기능은 메소드
를 만들어서 사용할 수 있다.[NEW]
를 추가하는 기능을 메소드를 통해 만들어 보자.1) 원하는 기능의 메소드를 모델에 추가
datetime.timedelta
는 날짜 혹은 시간 사이의 간격을 만들어 주기 위해 사용되며 인자로는 days, hours, minutes
등 조작하고자 하는 시간을 넣을 수 있다.from django.db import models
from django.utils import timezone
import datetime
class Question(models.Model):
question_text = models.CharField(max_length = 200)
pub_date = models.DateTimeField(auto_now_add = True)
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
2) [NEW]
를 앞에 붙이기 위해 __str__
수정
was_published_recently
메소드를 통해 이 데이터가 최근에 저장된 것인지 아닌지를 구분할 수 있게 되었다.[NEW]
를 보여지는 데이터 값으로 붙이기 위해서는 앞서 만든 메소드가 True이면 된다.class Question(models.Model):
question_text = models.CharField(max_length = 200)
pub_date = models.DateTimeField(auto_now_add = True)
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
def __str__(self):
if self.was_published_recently():
new_badge = '[new]'
else:
new_badge = ''
return f'{new_badge} 제목: {self.question_text}, 날짜: {self.pub_date}'
3) Django shell
을 통해 확인하기
from polls.models import *
Question.objects.all()
#output: <QuerySet [<Question: [new] 제목: 가장 좋아하는 계절은?, 날짜: 2023-04-24 17:16:45+00:00>, <Question: [new] 제목: 가장 좋아하는 디저트는?, 날짜: 2023-04-24 17:16:58+00:00>, <Question: [new] 제목: 커피 vs 녹차???, 날짜: 2023-04-24 17:57:35.166408+00:00>, <Question: [new] 제목: 휴가를 가실 계획인가요?, 날짜: 2023-04-24 18:44:47.059743+00:00>, <Question: [new] 제목: 가장 좋아하는 날씨는?, 날짜: 2023-04-24 19:52:14.187249+00:00>]>
1.
Django Shell
나가는 단축키
- 대부분의
Django
를 명령창에서 사용할 때 종료하는 기능은ctrl+C
인데Django Shell
의 경우exit()
를 쳐서 나가야 한다.