[210715 TIL] Django

Choi Rimยท2021๋…„ 7์›” 15์ผ
1

Django

๋ชฉ๋ก ๋ณด๊ธฐ
3/21
post-thumbnail

migrate

$ python manage.py migrate
  • migrate ๋ช…๋ น์€ ์•„์ง ์ ์šฉ๋˜์ง€ ์•Š์€ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ๋ชจ๋‘ ์ˆ˜์ง‘ํ•ด ์ด๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
    • Django๋Š” django_migrations ํ…Œ์ด๋ธ”์„ ๋‘์–ด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ ์šฉ ์—ฌ๋ถ€๋ฅผ ์ถ”์ ํ•œ๋‹ค.
  • ์ด ๊ณผ์ •์„ ํ†ตํ•ด ๋ชจ๋ธ์—์„œ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค๊ณผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์Šคํ‚ค๋งˆ ๋™๊ธฐํ™”๊ฐ€ ์ด๋ฃจ์–ด์ง„๋‹ค.

migration

  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด๋ž€?
    • ๋ชจ๋ธ์˜ ๋ณ€๊ฒฝ ๋‚ด์—ญ์„ DB ์Šคํ‚ค๋งˆ์— ์ ์šฉ์‹œํ‚ค๋Š” ์žฅ๊ณ ์˜ ๋ฐฉ๋ฒ•
      • ์Šคํ‚ค๋งˆ๋ž€?
        • DB๋‚ด์— ์–ด๋–ค ๊ตฌ์กฐ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š”๊ฐ€ ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์กฐ๋ฅผ ์Šคํ‚ค๋งˆ๋ผ๊ณ  ํ•œ๋‹ค.
    • ์žฅ๊ณ ๋Š” ORM(ํŒŒ์ด์ฌ ์–ธ์–ด๋ฅผ SQL๋ฌธ์œผ๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— models.py์™€ ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด DB ์Šคํ‚ค๋งˆ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ปจํŠธ๋กค ํ•˜๊ฒŒ ๋œ๋‹ค.
    • ์ด ๋•Œ DB ์Šคํ‚ค๋งˆ๋ฅผ git์ฒ˜๋Ÿผ ๋ฒ„์ „์œผ๋กœ ๋‚˜๋ˆ ์„œ ๊ด€๋ฆฌ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ๋Š” ์‹œ์Šคํ…œ์ด๋ผ ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.
  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ๋งค์šฐ ๊ธฐ๋Šฅ์ด ๊ฐ•๋ ฅํ•˜๋‹ค.
    • ๋งˆ์น˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐœ๋ฐœํ•  ๋•Œ์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ ํ…Œ์ด๋ธ”์— ์†๋Œ€์ง€ ์•Š๊ณ ๋„ ๋ชจ๋ธ์˜ ๋ฐ˜๋ณต์ ์ธ ๋ณ€๊ฒฝ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.
    • ๋™์ž‘ ์ค‘์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ž๋ฃŒ ์†์‹ค ์—†์ด ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜๋Š”๋ฐ ์ตœ์ ํ™” ๋˜์–ด ์žˆ๋‹ค.
  • ๋ชจ๋ธ์˜ ๋ณ€๊ฒฝ์„ ๋งŒ๋“œ๋Š” ์„ธ ๋‹จ๊ณ„์˜ ์ง€์นจ
    • models.py ์—์„œ ๋ชจ๋ธ์„ ๋ณ€๊ฒฝํ•œ๋‹ค
    • python manage.py makemigrations์„ ํ†ตํ•ด ๋ณ€๊ฒฝ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ๋งŒ๋“ ๋‹ค
    • python manage.py migrate ๋ช…๋ น์„ ํ†ตํ•ด ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ์šฉํ•œ๋‹ค.

migrate & makemigrations

  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ๋งŒ๋“œ๋Š” ๋ช…๋ น๊ณผ ์ ์šฉํ•˜๋Š” ๋ช…๋ น์ด ๋ถ„๋ฆฌ๋œ ์ด์œ 
    • ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์— ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ปค๋ฐ‹ํ•˜๊ณ  ์•ฑ๊ณผ ํ•จ๊ป˜ ์ถœ์‹œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

django cycle

  • ํด๋ผ์ด์–ธํŠธ์ธ ์‚ฌ์šฉ์ž๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ณด๊ธฐ ์œ„ํ•ด์„œ ์š”์ฒญ์„ ํ•˜๊ธฐ ๋œ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญ์„ ํ•˜๋ฉด ์›น ์„œ๋ฒ„์ธ Nginx ๋‚˜ Apache๊ฐ€ ์š”์ฒญ์„ ๋งž์ดํ•œ๋‹ค.
    • Nginx, Apache๋ผ๋Š” ์›น ์„œ๋ฒ„๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ, ์ด ๋‘˜์„ ํ”ํžˆ ๊ต์ฐจํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.
      • Django์—์„œ๋Š” ๊ฐœ๋ฐœ์„ ์œ„ํ•ด์„œ ๊ฒฝ๋Ÿ‰ ๊ฐœ๋ฐœ ์›น ์„œ๋ฒ„๊ฐ€ ์ด๋ฏธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ ์„ธํŒ…์ด ๋˜์–ด ์žˆ๋‹ค.
      • ๊ฐœ๋ฐœ์„ ํ•  ๋•Œ๋Š” ๊ฒฝ๋Ÿ‰ ์›น ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ค์ œ ๋ฐฐํฌํ•  ๋•Œ๋Š” Nginx๋‚˜ Apache์™€ ๊ฐ™์€ ์›น ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • WSGI๋Š” ์›น ์„œ๋ฒ„์™€ Django ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋œ๋‹ค.
  • ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ์ฃผ์†Œ๋ฅผ ์š”์ฒญํ•˜๋ฉด URL ํŒŒ์ผ์—์„œ ์š”์ฒญํ•œ ์ฃผ์†Œ๋ฅผ ์ž˜๊ฒŒ ๋‚˜๋ˆ„์–ด์ค€๋‹ค.
    • ์ด ๊ณผ์ •์„ ํŒŒ์‹ฑ(parsing)์ด๋ผ๊ณ  ํ•œ๋‹ค.
  • ์ž˜๊ฒŒ ๋‚˜๋ˆ„์–ด์ง„ ์ฃผ์†Œ๋“ค์€ ์—ญํ• ์— ๋งž๊ฒŒ view๋กœ ์ด๋™ํ•œ๋‹ค.
    • view์—๋Š” ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๊ฐ๊ฐ ๋งž๋Š” ์ž‘์—…์„ ํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค.
      • ์ฝ”๋“œ์˜ ์ข…๋ฅ˜
        • ์š”์ฒญ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ
        • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๊บผ๋‚ด์˜ด
        • pdf๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ž‘์—…
  • view ์ž‘์—…์ด ๋๋‚˜๋ฉด ๋””์ž์ธ ๋‹ด๋‹น์ธ template์œผ๋กœ ์ด๋™ํ•œ๋‹ค.
  • ์‚ฌ์šฉ์ž๋Š” ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋œ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ๋Š” ์œ„ ๊ณผ์ •์ด ๋๋‚œ ํ›„์— ์š”์ฒญํ•œ ํ™”๋ฉด์„ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

ํ”„๋กœ์ ํŠธ(project) vs ์•ฑ(app)

  • ํ”„๋กœ์ ํŠธ๋Š” ์•ฑ์˜ ๋ฌถ์Œ์ด๋‹ค.
  • ์•ฑ์€ ํŠน์ •ํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์•ฑ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‹ค.
    • ํŠน์ •ํ•œ ๊ธฐ๋Šฅ์ด๋ž€
      • ์•„์ด์Šคํฌ๋ฆผ ๊ฐ€๊ฒŒ๋ฅผ ์ฐจ๋ฆฌ๋Š”๋ฐ, ์ด ๊ฐ€๊ฒŒ๋ฅผ ์œ„ํ•œ ์•ฑ์„ ๋งŒ๋“ ๋‹ค๊ณ  ํ•˜์ž
      • ์•„์ด์Šคํฌ๋ฆผ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ด€๋ฆฌ ์•ฑ, ์ฃผ๋ฌธ์„ ์œ„ํ•œ ์ฃผ๋ฌธ ์•ฑ, ๊ฐ€๊ฒŒ ์ด๋ฒคํŠธ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์ด๋ฒคํŠธ ์•ฑ
      • ์œ„์™€ ๊ฐ™์ด ํŠน์ • ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์•ฑ์„ ๊ฐ๊ฐ ์ƒ์„ฑํ•ด์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

urls.py์˜ ์ „์ฒด์ ์ธ ํ๋ฆ„

mysite/urls
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]
polls/urls
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
  • ์ตœ์ƒ์œ„ url.py์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ url์„ ์—ฐ๊ฒฐํ•ด ์ฃผ์—ˆ๋‹ค.
    • ex) 127.0.0.1/polls ๋ผ๋Š” url์ด ์ตœ์ƒ์œ„ url์— ๋“ค์–ด์™”๋‹ค๋ฉด, ์ด url์„ ํŒŒ์‹ฑํ•ด์„œ polls๋ผ๋Š” ํ•ด๋‹น path๋ฅผ ์žก์•„๋‚ด๊ณ  polls์•ฑ์˜ url๋กœ ์—ฐ๊ฒฐ์‹œ์ผœ ์ค€๋‹ค.
    • ์ตœ์ƒ์œ„ url์—์„œ url์„ ํŒŒ์‹ฑํ•˜์—ฌ ๋ฐ›์•„์ฃผ๊ณ  path๋ณ„๋กœ ๋‹ค๋ฅธ ์•ฑ์œผ๋กœ ๋ถ„๊ธฐ๋ฅผ ์‹œ์ผœ์ค€๋‹ค
      • ์•ฑ์ด ์—ฌ๋Ÿฌ๊ฐœ ์žˆ๋‹ค๋ฉด url์— ๋”ฐ๋ผ ํŒŒ์‹ฑ์„ ํ•ด์ฃผ๊ณ  path์— ๋”ฐ๋ฅธ ์•ฑ์œผ๋กœ ๋ถ„๊ธฐ๋ฅผ ์‹œ์ผœ์ค€๋‹ค.
  • polls/urls๊ฐ€ ์ตœ์ƒ์œ„ urls.py์—์„œ ์š”์ฒญ์„ ์ „๋‹ฌ๋ฐ›์œผ๋ฉด path๋‚ด์—์„œ view.index๋ผ๋Š” view ๋‚ด๋ถ€๋กœ ์—ฐ๊ฒฐ์„ ์‹œ์ผœ์ค€๋‹ค.
  • view ๋‚ด๋ถ€์˜ index ํ•จ์ˆ˜์˜ ์‘๋‹ต์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•ด์ค€๋‹ค.

settings.py

mysite/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
  • ์„ธํŒ… ํŒŒ์ผ์—๋Š” ์ด๋Ÿฌํ•œ ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
  • INSTALLED_APPS ์•ˆ์— ์žˆ๋Š” ์•ฑ๋“ค์€ ๊ฐ๊ฐ์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๋‹ค.
  • INSTALLED_APPS์•ˆ์— ์•ฑ์„ ๋ช…์‹œํ•˜๋ฉด, '์ด๋Ÿฌํ•œ ์•ฑ๋“ค์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค.' ๋ผ๊ณ  Django์—๊ฒŒ ์ด์•ผ๊ธฐ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • ์œ„๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ค์ •๋œ ์•ฑ๋“ค์ด๋‹ค.
$ python manage.py migrate
  • ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” ์•ฑ๋“ค์€ ์ตœ์†Œํ•œ ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์œ„์˜ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋œ๋‹ค.

๋ชจ๋ธ ๋งŒ๋“ค๊ธฐ

  • tutorial์—์„œ ๋งŒ๋“œ๋Š” ์„ค๋ฌธ์กฐ์‚ฌ ์•ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์ €์žฅ์„ ํ•„์š”๋กœ ํ•œ๋‹ค.
    • ์งˆ๋ฌธ (Question)
      • ์งˆ๋ฌธ (question)
      • ๋ฐœํ–‰์ผ (publication date)
    • ์‚ฌ์šฉ์ž๊ฐ€ ์งˆ๋ฌธ์— ๋Œ€ํ•œ ์„ ํƒ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ (Choice)
      • ์„ ํƒ์ง€ (choice)
      • ํ‘œ (vote)
    • 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')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
  • ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  database ๋ชจ๋ธ์€ Question๊ณผ Choice๊ฐ€ ์žˆ๋‹ค.
    • Question: ์งˆ๋ฌธ ๋‚ด์šฉ, ์ƒ์„ฑ ๋‚ ์งœ
      • ์งˆ๋ฌธ์˜ ๋ฐ์ดํ„ฐํ˜•
        • question_text = models.CharField(max_length=200)
          • ๋ฌธ์ž, ์ตœ๋Œ€๊ธธ์ด 200์ž
        • pub_date = models.DateTimeField('date published')
          • ๋ฐœํ–‰์ผ, ์‹œ๊ฐ„ํ…Œ์ด๋ธ”์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
    • Choice: ์„ ํƒ์ง€์— ํ•ด๋‹นํ•˜๋Š” ์งˆ๋ฌธ, ํˆฌํ‘œ์ˆ˜
      • ์งˆ๋ฌธ์˜ ๋ฐ์ดํ„ฐํ˜•
        • question = models.ForeignKey(Question, on_delete=models.CASCADE)
          • ์™ธ๋ž˜ํ‚ค(ForeignKey): Question์ด๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ชจ๋ธ์„ ์ฐธ์กฐํ•˜๊ฒ ๋‹ค.
          • Choice ๋‚ด์— ์žˆ๋Š” question์€ ์ƒ์„ฑ๋œ Question์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋‹ค.
          • CASCADE: ์œ„์˜ class Question์ด ์‚ญ์ œ๊ฐ€ ๋˜๋ฉด Choice๋‚ด์˜ question๋„ ์‚ญ์ œ๊ฐ€ ๋œ๋‹ค๋ผ๋Š” ๋œป
  • ForeignKey
    • Question์ด๋ผ๋Š” ํ…Œ์ด๋ธ”์ด ์žˆ๊ณ , Choice๋ผ๋Š” ํ…Œ์ด๋ธ”์ด ์กด์žฌํ•œ๋‹ค.
    • Choice ํ…Œ์ด๋ธ” ๋‚ด์˜ question์€ Question ํ…Œ์ด๋ธ”์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค.
    • ํ•˜๋‚˜์˜ Question ํ…Œ์ด๋ธ”์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ Choice๋ฅผ ๊ฐ–๋Š” ๊ตฌ์กฐ์ด๊ธฐ ๋•Œ๋ฌธ์— 1:๋‹ค ๊ตฌ์กฐ์ด๋‹ค.

๋ชจ๋ธ์˜ ํ™œ์„ฑํ™”

  • ์žฅ๊ณ ์˜ ์ฒ ํ•™
    • ์•ฑ๋ณ„๋กœ ๊ธฐ๋Šฅ์ด ๋‚˜๋‰˜์–ด์ ธ์žˆ๋‹ค.
    • ์•ฑ์„ ๋“ฑ๋ก์„ ํ•˜๋Š๋ƒ ํ•˜์ง€ ์•Š๋Š๋ƒ์— ๋”ฐ๋ผ์„œ ์•ฑ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒ ๋‹ค, ์•ฑ์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค ๋ช…์‹œ๋ฅผ ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.
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',
]
  • ์œ„์ฒ˜๋Ÿผ ์„ธํŒ… ํŒŒ์ผ์— ๋งŒ๋“  polls ์•ฑ์„ ๋“ฑ๋กํ•ด ์ค€๋‹ค.
  • 'polls.apps.PollsConfig'
    • 'polls ์•ฑ ํŒŒ์ผ์•ˆ์˜ apps ํŒŒ์ผ์˜ PollsConfig๋ฅผ ๋“ฑ๋กํ•˜๊ฒ ๋‹ค.' ๋ผ๋Š” ๋œป
$ python manage.py makemigrations polls
  • makemigrations
    • ๋ชจ๋ธ์„ ์ž‘์„ฑํ•˜๊ณ  migration์ด๋ผ๋Š” ์žฅ์†Œ์—๋‹ค ์ด ๋ชจ๋ธ๋“ค์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด์— ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋„๋ฅผ ๋งŒ๋“œ๋Š” ์ž‘์—…
python manage.py makemigrations polls
Migrations for 'polls':
  polls/migrations/0001_initial.py
    - Create model Question
    - Create model Choice
  • ์œ„์˜ ํ™”๋ฉด์ด ์ถœ๋ ฅ๋˜์—ˆ๋‹ค๋ฉด migrations ๋””๋ ‰ํ† ๋ฆฌ์•ˆ์— 0001_initial.py์ด๋ผ๋Š” ํŒŒ์ผ์ด ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.
polls/migrations/0001_initial.py
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Question',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('question_text', models.CharField(max_length=200)),
                ('pub_date', models.DateTimeField(verbose_name='date published')),
            ],
        ),
        migrations.CreateModel(
            name='Choice',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('choice_text', models.CharField(max_length=200)),
                ('votes', models.IntegerField(default=0)),
                ('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.question')),
            ],
        ),
    ]
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚ด์˜ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์„ค๊ณ„๋„๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Applying polls.0001_initial... OK
  • ์ด์ œ migrate๋ฅผ ํ•˜๋ฉด ์ž‘์—…์ด ์™„๋ฃŒ๋œ๋‹ค.

API ๊ฐ€์ง€๊ณ  ๋†€๊ธฐ

  • API๋ž€
    • ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฝ‘์•„๋‚ผ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด๋†“์€ ํ•จ์ˆ˜,์„œ๋ฒ„, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ๋†“์€ ํ•จ์ˆ˜๊ฐ™์€ ๊ฒƒ
>>> from polls.models import Choice, Question 
  • ๋งŒ๋“ค์–ด๋†“์€ polls์•ˆ์˜ ๋ชจ๋ธ๋‚ด์˜ Choice, Question์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋ผ๊ณ  ์ถ”๊ฐ€๋ฅผ ํ•˜๋Š” ์ž‘์—…
>>> Question.objects.all()
<QuerySet []>
  • ํ˜„์žฌ Question ๋‚ด์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์™€๋ผ
>>> from django.utils import timezon
  • Question ๋ชจ๋ธ์—๋Š” ์งˆ๋ฌธ, ๋ฐœํ–‰์ผ์ด ์žˆ์—ˆ๋‹ค.
  • ๋ฐœํ–‰์ผ ์‹œ๊ฐ„์„ ์ž…๋ ฅํ•˜๊ธฐ ์œ„ํ•ด์„œ timezone์ด๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ importํ•˜๋ฉด ๋œ๋‹ค.
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save()
>>> q.id
1
  • Question์„ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•œ๋‹ค.
  • id๋Š” ๋ชจ๋ธ์„ ์ƒ์„ฑํ•  ๋•Œ ๋ช…์‹œ๋ฅผ ํ•˜์ง€ ์•Š๋”๋ผ๋„ Django์—์„œ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ํ•„๋“œ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.
    >>> Question.objects.all()
    <QuerySet [<Question: Question object (1)>]>
    
  • ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์œผ๋‹ˆ Question์˜ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋ชจ๋‘ ๋ถˆ๋Ÿฌ์˜ค๋ฉด ํ•˜๋‚˜๊ฐ€ ์กด์žฌํ•œ๋‹ค๊ณ  ๋œฌ๋‹ค!
  • ๊ทธ๋Ÿฐ๋ฐ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณผ๋•Œ๋Š” object (1)๋กœ ์ถœ๋ ฅ์ด ๋˜๋Š”๋ฐ, ์–ด๋–ค ๋ฐ์ดํ„ฐ์ธ์ง€ ์ž˜ ๊ตฌ๋ถ„์ด ๊ฐ€์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.
  • ๋ชจ๋ธ ๋‚ด์— __str__() ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋ฌธ์ž๋กœ ์ถœ๋ ฅ์ด ๋˜๊ฒŒ ๋œ๋‹ค.
polls/models.py
from django.db import models

# Create your models here.

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
  • ๋ชจ๋ธ ๋‚ด์— ์œ„์ฒ˜๋Ÿผ __str__ ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.
import datetime

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


class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
  • ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ•„์š”ํ•œ ์ปค์Šคํ…œ ๋ฉ”์„œ๋“œ ๋˜ํ•œ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์œ„์—์„œ ์ถ”๊ฐ€ํ•œ __str__์„ ํฌํ•จํ•œ ์ฝ”๋“œ๋ฅผ ์ง€์šฐ์ง€ ๋ง๊ณ  class Question์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
  • ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•จ์ˆ˜๋ฅผ ์‚ดํŽด๋ณด์ž
    • timezone.now() : ํ˜„์žฌ ์‹œ๊ฐ„
    • datetime.timedelta(days=1) : ํ•˜๋ฃจ ์ „๋‚ ์˜ ์‹œ๊ฐ„
    • timezone.now() - datetime.timedelta(days=1)
      • ํ˜„์žฌ์‹œ๊ฐ„์—์„œ ํ•˜๋ฃจ ์ „๋‚ ์˜ ์‹œ๊ฐ„์„ ๋นผ์ค€๋‹ค.
      • ํ˜„์žฌ๋กœ๋ถ€ํ„ฐ ํ•˜๋ฃจ ์ฐจ๊ฐํ•œ ์–ด์ œ์˜ ์‹œ๊ฐ„ ๋ฐ˜ํ™˜
    • return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
      • ์–ด์ œ ์ดํ›„๋กœ ๋ฐ˜ํ™˜ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฆฌํ„ด๋จ
    • ๋งŽ์€ ๋ชจ๋“ˆ๋“ค์„ ๋‹ค ์•Œ ์ˆ˜ ์—†์œผ๋‹ˆ ๊ทธ ๋•Œ ๊ทธ ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ตํ˜€๋‚˜๊ฐ€์ž
>>> Question.objects.all()
<QuerySet [<Question: What's new?>]>
  • ์œ„ ๋ชจ๋ธ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ €์žฅํ•˜๊ณ  shell์„ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋ฉด ๋ฌธ์ž๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

django admin

  • django์˜ ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋Š” admin๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • admin์€ ์‚ฌ์ดํŠธ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ด€๋ฆฌ์ž ์ „์šฉ ์‚ฌ์ดํŠธ์ด๋‹ค.
  • html ํŽ˜์ด์ง€๋งŒ ์กด์žฌํ•˜๋Š” ์‚ฌ์ดํŠธ๊ฐ€ ์•„๋‹ˆ๊ณ ์„œ๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— admin์ด ์กด์žํ•œ๋‹ค.
  • ์ปจํ…์ธ ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • django๋Š” model, ์ฆ‰ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ui๊ฐ€ ์กด์žฌํ•˜๋Š” ํ™”๋ฉด์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” admin์„ ๋งŒ๋“ค์–ด์ค€๋‹ค.
$ python manage.py createsuperuser
  • ๊ด€๋ฆฌ์ž์‚ฌ์ดํŠธ์— ๋กœ๊ทธ์ธ ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž๋ฅผ ๋งŒ๋“ ๋‹ค.
$ python manage.py runserver
  • ์„œ๋ฒ„๋ฅผ ๋™์ž‘ํ•œ๋‹ค.

  • ์„œ๋ฒ„๋ฅผ ๋™์ž‘ํ•œ ๋’ค http://127.0.0.1:8000/admin/ ์ฃผ์†Œ๋กœ ์ ‘์†ํ•˜๋ฉด ์œ„์™€ ๊ฐ™์€ ์ฐฝ์ด ๋œฌ๋‹ค.

  • ์—ฌ๊ธฐ์„œ ์ž…๋ ฅํ•œ url์€ mysite/urls.py ์•ˆ์— ์กด์žฌํ•œ๋‹ค.

  • ์ด์ œ admin ํ™”๋ฉด์—์„œ ์งˆ๋ฌธ ์ˆ˜์ •๊ณผ ์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

<์ฐธ๊ณ >

profile
https://rimi0108.github.io/

0๊ฐœ์˜ ๋Œ“๊ธ€