Django
- 환경설정
- 관계형 데이터베이스
- Model 만들기
- 다양한 필드 활용
- 관리자 계정 생성
- Django Admin - 모델 등록
- Django Shell
python 설치
python 가상 환경 설정
프로젝트마다 가상환경을 설정해줘야 하는 이유
서로 다른 유형과 목적의 프로젝트들을 한 공간에 넣어서 관리한다면, 매번 하나의 프로젝트를 실행할 때마다 그에 맞춰서 환경을 체크하고 변경해주어야 하며 심한 경우에는 프로젝트 간의 충돌이 발생할 수도 있기 때문
가상 환경 생성
$ py -m venv project-name
가상 환경 활성화
$ project-name\Scripts\activate.bat
가상 환경 비활성화
$ deactivate
Django 설치
$ py -m pip install Django
설치 확인
$ django-admin --version
mysite라는 이름을 가진 프로젝트 생성
$ django-admin startproject mysite
mysite로 이동
$ cd mysite
생성한 프로젝트를 서버에서 실행
$ python manage.py runserver
실행된 서버 확인
App의 특성
프로젝트 내에 App 생성
$ python manage.py startapp app_name
Http Response 해보기
요구 조건 :
http://127.0.0.1:8000/polls를 입력 받았을 때, Hello, World를 출력하기
코드 생성
polls/views.py# 출력문
# Http response를 하기 위함
from django.http import HttpResponse
# index함수가 호출되면 hello world를 출력해라
def index(request):
return HttpResponse("Hello, world.")
polls/urls.py# http://127.0.0.1:8000/polls/path 입력이 들어왔을 때,
# 여기서 path가 ''이면 views의 index로 연결
from django.urls import path
# 현재 App에서 view를 가져와라
from . import views
urlpatterns = [
# url이 비어서 들어온다면
# views의 index로 보내고 이름은 index로 해라
path('', views.index, name='index'),
]
mysite/urls.py# http://127.0.0.1:8000/path 에서
# path에 따른 연결을 진행
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
# path에 polls란 url이 들어오면
# polls 폴더 내 urls로 연결해라
path('polls/', include('polls.urls')),
# path에 admin이란 url이 들어오면 admin.site.urls으로 연결해라
## path('admin/', admin.site.urls),
path('admin/', admin.site.urls),
]
정의
데이터를 행과 열로 이루어진 테이블의 형태로 구성하고, 테이블 간의 관계를 정의하는 데이터베이스
테이블
데이터베이스에서 행과 열로 구성되어 있는 데이터의 집합
열(column)
테이블의 각 행을 고유하게 식별할 수 있는 열
다른 테이블의 primary key를 참조하는 열
행(row)
테이블에 저장된 데이터 레코드(
Record)를 의미
레코드(Record)
하나의 단위로 표현되어지는 필드들의 집합
고유한 값을 가지는 Primary Key로 식별됨
Model이란
원하는 기능 :
질문 : 여름에 놀러간다면 어디에 갈래?
답 : 산, 강, 바다, 도심 호캉스
-> 이 모델에 맞는 테이블을 만드는 것
필요한 절차 :
모델 생성
polls.models.py# 모델을 만드려면 models.Model을 상속 받아야함
class Question(models.Model):
# 텍스트 형식의 질문을 하기 위해 Char형태로 만들어줌
question_text = models.CharField(max_length=200)
# 이 질문을 만든 날짜를 기록
pub_date = models.DateTimeField('data published')
# 질문에 대한 옵션을 만들기 위함
class Choice(models.Model):
# 이 question은 하나의 질문에 여러가지 옵션 중 하나,
# 어떤 질문에 대한 옵션인지를 가리켜야하므로
# Question의 unique id를 저장 (Question의 PK를 참조하여 FK로 만듬)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
# 몇 개의 투표를 받았는 지 기록
votes = models.IntegerField(default=0)
마이그레이션
마이그레이션 : 모델의 변경 내역을 DB 스키마에 적용시키는 Django의 방법
Migration을 만들기 전에 App을 등록해줘야함
( 장고의 기능은 설치된 App에 대해서 Migration을 만들기 때문 )
mysite.setting.py# mysite.setting.py의 INSTALLED_APPS에 polls를 등록
# => 등록하는 법 : polls.apps.py에 있는 PollsConfig함수를 등록
INSTALLED_APPS = [
'polls.apps.PollsConfig',
...,
]
Migration 명령어
python manage.py makemigrations polls

Migration 내용 확인
python manage.py sqlmigrate polls 0001

INDEX 테이블이 만들어진 이유?테이블 생성
python manage.py migrateDjango의 필드 확인하는 법
Model 수정 및 Migration
polls.models.pyclass Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
# 새로 추가
is_something = models.BooleanField(default=False)
average_score = models.FloatField(default=0.0)
Migrate 후 DB 확인
$ sqlite3 db.sqlite3
sqlite3 내에서 DB 살펴보기
table 목록 확인
.tables
Migration 기록 확인
SELECT * FROM django_migrations;
Polls Table 구조 확인
.schema polls_question
Migration Rollback
python manage.py migrate polls 0001
( 0002를 생성했었더라면 0002파일을 지워줘야 다음 Migration때, 반영이 되지 않는다. )
Admin(관리자) 페이지
일반적으로, 시스템을 관리하는 관리자들이 데이터를 추가, 수정하는 페이지
관리자 계정
admin 페이지를 개발자가 일일이 만들기보다,
Django에서는 만든 모델들을 기반으로 데이터를 만들고 읽고 수정할 수 있는 기능을 제공
관리자 계정 생성
python manage.py createsuperuser
Admin 접속 방법
http://127.0.0.1:8000/admin
polls.admin.pyfrom django.contrib import admin
# polls내 models에 있는 모든 함수를 불러옴
from .models import *
# Question, Choice 모델을 불러옴
admin.site.register(Question)
admin.site.register(Choice)
polls.models.pyclass Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('data published')
# 자동 생성 되는 id 컬럼을 원하는 제목으로 정의
# __str__(self) : 자기 자신의 문자열 정의를 표현
def __str__(self):
return f'제목: {self.question_text}, 날짜: {self.pub_date}'
Django Shell 실행
python manage.py shell
( 장고 환경을 그대로 로딩, 정의한 모델들을 활용 가능 )
Question 모델 import
from polls.models import *
( 직접 경로 지정 )
Question의 객체들 확인
Question.objects.all()
보다 세부적인 접근도 가능
choice = Choice.objects.all()[0]
choice.question
choice.question.question_text
qustion = Question.objects.all()[0]
question.choice_set.all()
현재 시간 구하기
datetime
from datetime import datetime
datetime.now()
timezone
datetime에 비해 tzinfo 정보가 추가됨,
주로 django에서는 timezone을 사용
from django.utils import timezone
timezone.now()
Record 생성 ( Data 생성 )
e.g.)
# Django shell
from polls.models import *
# q1 객체 생성
q1 = Question(question_text = "커피 vs 녹차 ")
# timezome import
from django.utils import timezone
# q1에 pub_date 정보를 추가
q1.pubdate = timezone.now()
# table에 업로드 ( Record 생성 )
q1.save()
# q1의 choice 옵션을 추가
q1.choice_set.create(choice_text='a')
q1.choice_set.create(choice_text='b')
# 이런식으로도 q1에 choice 옵션 추가 가능
choice_c = Choice(choice_text='c',question=q1)
choice_c.save()
polls.modes.py : pub_date 수정# pub_date가 자동 생성되게끔 수정
pub_date = models.DateTimeField(auto_now_add=True)Record 수정 및 삭제
수정
from polls.models import *
# 마지막 Question 객체를 호출
q = Question.objects.last()
# q의 내용을 수정
q.question_text = q.question_text + '???'
# 저장하여 반영
q.save()
삭제
# 마지막 객체 참조 'a','b','c' 중 'c'
choice = Choice.objects.last()
# choice의 question 저장
q = choice.question
# choice 삭제 'c' 삭제
choice.delete()
# 삭제 됬는지 확인
q.choice_set.all()
# id가 비어있는 것으로도 확인 가능
choice.id
모델 필터링 (Model Filtering)
모델을 통해서 Table에서 다양한 조건에 맞는 Record를 불러오는 방법
참조 : https://docs.djangoproject.com/en/5.0/ref/models/querysets/#id4
ex1)
from polls.models import *
# id가 1인 question 객체를 불러옴
Question.objects.get(id=1)
# question_text가 '휴가를'으로 시작하는 객체를 불러옴
# __? : 조건
Question.objects.get(question_text__startswith='휴가를')
# pub_date에 second가 59인 객체 불러옴
Question.object.get(pub_date__second=59)
# get : 하나의 객체만 불러올 수 있음
# filter : 여러 개의 객체를 불러올 수 있음
Question.objects.filter(pub_date__year=2024)
# count도 가능
Question.objects.all().count()
# query를 출력하면 사용된 SQL문을 확인할 수 있음
print(Question.objects.filter(pub_date__year=2024).query)
ex2)
# '휴가'가 들어간 질문을 추가
q = Question(question_text="휴가를 가실 계획인가요?")
q.save()
# '휴가'가 들어간 모든 질문을 가져옴
Question.objects.filter(question_text__contains='휴가')
# gt : ~ 보다 큰
# update : 수정
choice = Choice.objects.first()
choice.votes = 5 # choice의 votes를 5로 변경
choice.save() # 이를 저장
# votes가 0보다 큰 모든 객체를 0으로 수정 및 저장
Choice.objects.filter(votes__gt=0).update(votes=0)
# delete
choice.votes = 5
choice.save()
Choice.objects.filter(votes__gt=0).delete()
# regex : r'^시작 문자열.*0개 이상의 임의의 문자열'
# '휴가' 단어로 시작하고 '어디' 단어가 포함된 질문을 가져옴
q = Question(question_text="휴가 계획이 있나요?")
q.save()
Question.objects.filter(question_text__regex=r'^휴가.*어디')
# 위와 동일한 표현
Question.objects.filter(question_text__startswith='휴기').filter(question_text__contains='어디')
Django 모델 관계기반 필터링

e.g.)
from polls.models import *
# 휴가라는 질문에 대한 Choice들을 선택
# question의 외래키로 들어가 휴가로 시작하는 choice들을 가져옴
Choice.objects.filter(question__question_text__startswith='휴가')
# exclude : 이 조건을 포함하지 않는 모든 객체들을 가져옴
Question.objects.exclude(question_text__startswith='휴가')
모델 메소드
ex) save()
( 모델이 Models.Model을 상속받기 때문에, 그 내부에 정의된 save() 메소드를 사용할 수 있음 )
polls.modes.py : 메소드 추가
from django.db import models
from django.utils import timezone
import datetime
class Question(models.Model):
...
# 메소드 추가
# 어제보다 최근에 만들어진 경우
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}
...
shell에서 확인
from polls.models import *
q = Question.objects.first()
# q가 오늘 만들어졌기에 True
q.was_published_recently()