Model

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

# 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',
            ],
        },
    },
]
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