Model in Django

Django ๊ธฐ๋ณธ ํ๋ฆ„

  1. url์„ ์ •์˜ํ•œ๋‹ค

    • urls.py๋Š” ์ด์ •ํ‘œ๋‹ค!

  2. views.py์— ์‹คํ–‰ํ•  ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค

  3. ๋ฐ˜ํ™˜ํ•  html๋ฅผ ๋งŒ๋“ ๋‹ค

Django project / app ์„ค์ •

  • Django๋Š” ํ•˜๋‚˜์˜ project๊ฐ€ ๋ณต์ˆ˜์˜ app์„ ๊ฐ€์ง€๋Š” ๊ตฌ์กฐ๋กœ ๋˜์–ด์žˆ๋‹ค

  • ๊ฐ๊ฐ์˜ app๋“ค์€ MTV pattern์„ ๊ฐ–๊ณ  ์žˆ๋‹ค

  • ๋‹ค์ค‘ app์œผ๋กœ ๊ตฌ์„ฑ๋˜๋Š” ๊ฒฝ์šฐ ์ด๋ฆ„ ์ค‘๋ณต์ด ๊ฐ€๋Šฅํ•˜์—ฌ template/{app์ด๋ฆ„}/{}.html ์œผ๋กœ ๊ตฌ์„ฑํ•œ๋‹ค

    • why?

      • ๊ฐœ๋ณ„ app์— ์ƒ์„ฑ๋œ templates folder์˜ ํ•˜์œ„ directory๋Š” template file๋กœ ํ™œ์šฉ๋œ๋‹ค (default)

      • Django๋Š” template file์„ ํƒ์ƒ‰ํ•˜๋Š” ๊ณผ์ •์—์„œ settings.py์˜ DIR๊ณผ INSTALLED_APPS์˜ ์„ ์–ธ ์ˆœ์„œ์— ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„ ์ค‘๋ณต์„ ๋ง‰๊ณ ์ž template ๋ฐ‘์— app ์ด๋ฆ„๊ณผ ๋™์ผํ•œ folder๋ฅผ ๋‘”๋‹ค

1. Project ์ƒ์„ฑ

$ django-admin startproject {ํ”„๋กœ์ ํŠธ ๋ช…}

2. Project ๊ธฐ๋ณธ ์„ค์ • - settings.py

  1. # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # app/templates/ ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํด๋”์— templates๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ
        'DIRS': [os.path.join(BASE_DIR, 'templates')], # project root ๊ฒฝ๋กœ์— `templates` folder๋ฅผ ๋งŒ๋“ค ๊ฒฝ์šฐ `templates`๋งŒ
        # ๋“ฑ๋ก๋œ ์•ฑ์— templates folder๋ฅผ ๋ชจ๋‘ ๋‹ค ๊ฐ™์€ templates ๋กœ ๋ณด๊ฒ ๋‹ค => True
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
  1. DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.sqlite3',
         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
     }
    }

3. app ์ƒ์„ฑ (articles)

  • app์ด๋ฆ„์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ณต์ˆ˜ํ˜•์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค

    $ python manage.py startapp articles
  • app ๋“ฑ๋ก

    settings.py

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'articles',
        'django_extensions',
    ]

4. urls.py ์ƒ์„ฑ

ํ”„๋กœ์ ํŠธ ํด๋”

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('articles/',include('articles.urls'))
]

๊ฐœ๋ณ„ app

from django.urls import path
from . import views

urlpatterns = [
    #/articles/
    path('new/', views.new),
    path('create/', views.create),
    path('', views.index),
    ]

MTV์˜ ์—ญํ• 

view

  • url

  • request (์š”์ฒญ ๊ด€๋ จ ์ •๋ณด)

  • return render()

Template

  • html

  • DTL

  • ๋ฐ˜๋ณต / ๋ณด๊ฑด /ํ•„ํ„ฐ

Model

  • DB

Model in Django

Model

: Data์— ๋Œ€ํ•œ ๋‹จ์ผ ์ •๋ณด ์†Œ์Šค

Migrations

: ๋ชจ๋ธ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ๋“ค์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ์— ๋ฐ˜์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•

Migration ํ๋ฆ„

  1. Model ์ƒ์„ฑ/์ˆ˜์ •/์‚ญ์ œ ๋“ฑ

  2. migration ํŒŒ์ผ ์ƒ์„ฑ

    • migration file์€ model์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๊ธฐ๋กํ•˜๊ณ , database์— ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ๋“ค๋กœ ๊ตฌ์„ฑ๋œ๋‹ค

    • migration file์€ database scheme๋ฅผ ์œ„ํ•œ ๋ฒ„์ „๊ด€๋ฆฌ ์‹œ์Šคํ…œ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ž! -> git

  3. migrate๋ฅผ ํ†ตํ•œ database์— ์ ์šฉ

Model

Migration

ORM (Query mtehods, QuerySet API)

MTV pattern์—์„œ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ

Model๋กœ ์ •์˜๋œ db schema๋ฅผ ๋ฐ˜์˜

db๋ฅผ ์กฐ์ž‘ํ•˜๋Š” query๋ฌธ (python ๊ฐ์ฒด ์กฐ์ž‘์œผ๋กœ ๊ฐ€๋Šฅํ•˜๋‹ค)

Model ํ™œ์šฉ

1. model ์ •์˜

models.py

from django.db import models

# Create your models here.

class Article(models.Model):
    title = models.CharField(max_length=140)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
  • models.Model์„ ์ƒ์†๋ฐ›์€ class๋ฅผ ์ƒ์„ฑํ•œ๋‹ค

  • ์†์„ฑ์œผ๋กœ๋Š” ๋‚ด๊ฐ€ ๊ตฌ์„ฑํ•˜๊ณ  ์‹ถ์€ table์˜ column์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๊ณ , data type์— ๋งž์ถฐ์„œ field๋ฅผ ์ •์˜ํ•œ๋‹ค

  • id ํ•„๋“œ๋Š” ์ž๋™์ ์œผ๋กœ pk ๊ฐ’์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.

  • ์œ„์—์„œ ์ •์˜๋œ ํ•„๋“œ์™€ ์˜ต์…˜ ์ •๋ณด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

    • CharField :

      • max_length : ํ•„์ˆ˜

    • DateTimeField

      • auto_now_add : (์„ ํƒ) ์ƒ์„ฑ์‹œ์—๋งŒ ์ž๋™์œผ๋กœ ํ•ด๋‹น ์‹œ๊ฐ„ ๊ฐ’ ์„ค์ •

      • auto_now : (์„ ํƒ) ์ˆ˜์ •์‹œ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ํ•ด๋‹น ์‹œ๊ฐ„ ๊ฐ’ ์„ค์ •

  • ์ด์™ธ์˜ ํ•„๋“œ๋Š” https://docs.djangoproject.com/ko/2.1/ref/models/fields/#field-types ๋งํฌ์—์„œ ํ™•์ธ!

CharField vs TextField()

: ์‹ค์ œ๋กœ <form> tag๋กœ data๋ฅผ ๋ฐ›์„๋•Œ <input>์œผ๋กœ ๋ฐ›์„ ์ง€ <textarea> ๋กœ ๋ฐ›์„์ง€์— ๋”ฐ๋ผ ์„ ํƒํ•˜๊ธฐ

2. migration

Migrations are Djangoโ€™s way of propagating changes you make to your models (adding a field, deleting a model, etc.) into your database schema. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ django์—์„œ ๋ชจ๋ธ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ์— ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค.

2-1. makemigrations

$ python manage.py makemigrations
Migrations for 'articles':
  articles/migrations/0001_initial.py
    - Create model Article
  • ์ •์˜๋œ model์„ database์— ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” migration ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด migration file์„ ์ƒ์„ฑํ•œ๋‹ค

  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์€ ๋ชจ๋ธ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์€ ๊ธฐ๋กํ•˜๋ฉฐ, app ๋ณ„๋กœ ์žˆ๋Š” migrations/ ํด๋”์— ๊ธฐ๋ก๋œ๋‹ค. ์ตœ์ดˆ์— 0001_initial.py ๋ผ๋Š” ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์–ด ์žˆ์„ ๊ฒƒ์ด๋‹ค.

  • migration file์€ model์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๊ด€๋ฆฌํ•œ๋‹ค

    • Modeling ํ•œ ๋‚ด์šฉ์„ db์— ๋ฐ˜์˜ ํ•  ์ค€๋น„๋ฅผ ํ•˜๋Š” ๊ฒƒ!

2-2. migrate

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, articles, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying articles.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying sessions.0001_initial... OK
  • ์ƒ์„ฑ๋œ migration file์„ database์— ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•œ ๋ช…๋ น์–ด

  • ์œ„์™€ ๊ฐ™์ด ๋งŽ์•„ ๋ณด์ด๋Š” ๊ฒƒ์€ django๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ๊นŒ์ง€ ๋ฐ˜์˜๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค

    • ์•ž์œผ๋กœ๋Š” ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ๊ณผ ๋™์‹œ์— python manage.py migrate ๋ฅผ ํ•˜์ž!

Migration Flow

  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ƒ์„ฑ

    $ python manage.py makemigrations
  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ DB ๋ฐ˜์˜ ์—ฌ๋ถ€ ํ™•์ธ

    $ python manage.py showmigratons
  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์— ๋Œ€์‘๋˜๋Š” SQL๋ฌธ ์ถœ๋ ฅ

    $ python manage.py sqlmigrate app_label migration_name
  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ DB์— ์ตœ์ข… ๋ฐ˜์˜

    $ python manage.py migrate

+

admin ๋“ฑ๋ก

# django_crud/articles/admin.py
from django.contrib import admin

# Register your models here.
from .models import Article
admin.site.register(Article)

Django ORM

๊ธฐ๋ณธ์ ์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์กฐ์ž‘์„ CRUD(Create, Read, Update, Delete) operation ์ด๋ผ๊ณ  ํ•œ๋‹ค.

ORM (Object Relational Mapping)

  • DB์™€ OOP language ๊ฐ„์˜ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” data๋ฅผ ๋ณ€ํ™˜ํ•˜๋Š” programming ๊ธฐ๋ฒ•

    • ORM์€ db์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฐ’์„ object๋กœ mapping ํ•ด์ค€๋‹ค!

      • Python ๊ฐ์ฒด ์กฐ์ž‘(method ํ˜ธ์ถœ)์œผ๋กœ db๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๊ฒƒ!

Django shell

python interactive interpreter๋ฅผ django ํ”„๋กœ์ ํŠธ์— ๋งž๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ

$ python manage.py shell
  • ์ถ”๊ฐ€์ ์ธ ํŒจํ‚ค์ง€ ์„ค์น˜๋ฅผ ํ†ตํ•ด ํŽธํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    $ pip install django-extensions ipython
    • django-extensions ๋Š” django ๊ฐœ๋ฐœ์— ์žˆ์–ด์„œ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ๋“ค์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•œ๋‹ค.

    • ipython ์€ ์ธํ„ฐ๋ ‰ํ‹ฐ๋ธŒ ์‰˜์„ ์กฐ๊ธˆ ๋” ํŽธํ•˜๊ฒŒ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์„ค์น˜

  • ์„ค์น˜ ์ดํ›„์—, settings.py ์— ๋‹ค์Œ์˜ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค. (์ฝค๋งˆ ์œ ์˜)

    # django_crud/settings.py
    INSTALLED_APPS = [
        ...
        'django_extensions',
        'articles',
    ]
  • ๊ทธ๋ฆฌ๊ณ  ์ด์ œ๋ถ€ํ„ฐ๋Š” ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

    $ python manage.py shell_plus

1. ์ƒ์„ฑ

article = Article()
article.title = '์ œ๋ชฉ'
article.content = '๋‚ด์šฉ'
article.save()

2. ์กฐํšŒ

  • ์ „์ฒด ๋ฐ์ดํ„ฐ ์กฐํšŒ

    Article.objects.all()
    >> <QuerySet [<Article: Article object (1)>]>
  • ๋‹จ์ผ ๋ฐ์ดํ„ฐ ์กฐํšŒ

    ๋‹จ์ผ ๋ฐ์ดํ„ฐ ์กฐํšŒ๋Š” ๊ณ ์œ ํ•œ ๊ฐ’์ธ id๋ฅผ ํ†ตํ•ด ๊ฐ€๋Šฅํ•˜๋‹ค.

    Article.objects.get(id=1)
    >> <Article: Article object (1)>
    In [2]: Article.objects.get(id=3)                                         
    Out[2]: Title: sample title & Content: sample content
    
    In [3]: Article.objects.get(pk=3)                                         
    Out[3]: Title: sample title & Content: sample content
    • id == pk!

      • ์ค‘๋ณต์„ ๋ถˆํ—ˆํ•œ๋‹ค

3. ์ˆ˜์ •

a1 = Article.objects.get(id=1)
a1.title = '์ œ๋ชฉ ์ˆ˜์ •'
a1.save()
  • ์ˆ˜์ •์ด ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฐ์ดํ„ฐ ์กฐํšŒ๋ฅผ ๋‹ค์‹œ ํ•ด๋ณด์ž

4. ์‚ญ์ œ

a1 = Article.objects.get(id=1)
a1.delete()
>> (1, {'articles.Article': 1})

Admin ํŽ˜์ด์ง€ ํ™œ์šฉ

1. ๊ด€๋ฆฌ์ž ๊ณ„์ • ์ƒ์„ฑ

$ python manage.py createsuperuser
์‚ฌ์šฉ์ž ์ด๋ฆ„ (leave blank to use 'ubuntu'): admin1
์ด๋ฉ”์ผ ์ฃผ์†Œ:
Password:
Password (again):
Superuser created successfully.

2. admin ๋“ฑ๋ก

admin ํŽ˜์ด์ง€๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” app ๋ณ„๋กœ ์žˆ๋Š” admin.py์— ์ •์˜ ๋˜์–ด์•ผ ํ•œ๋‹ค

# django_crud/articles/admin.py
from django.contrib import admin

# Register your models here.
from .models import Article
admin.site.register(Article)

3. ํ™•์ธ

  • /admin/ url๋กœ ์ ‘์†ํ•˜์—ฌ, ๊ด€๋ฆฌ์ž ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ

+

Tips

$ python manage.py sqlmigrate articles 0001
BEGIN;
--
-- Create model Article
--
CREATE TABLE "articles_article" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(20) NOT NULL, "content" text NOT NULL);
COMMIT;

Fat Model

  • MVC

    • M (C) V

  • MTV

    • M (V) T

    -> Make model fat!!!!

Last updated