๐Ÿ”ฅTIL#3. Django tutorial 2-1

๋ฐฑ์Šน์ง„ยท2020๋…„ 11์›” 2์ผ
0

wecode Django ์‹ค์Šต

๋ชฉ๋ก ๋ณด๊ธฐ
5/16

What you will learn?

  1. Framework์—์„œ ์ œ๊ณตํ•˜๋Š” ORM์— ๋Œ€ํ•œ ์ดํ•ด
  2. Models.py๋กœ Database ์—ฐ๋™.
  3. table๊ณผ column ์— ๋Œ€ํ•œ CRUD ๋ฐฉ๋ฒ•.

1. Framework์—์„œ ์ œ๊ณตํ•˜๋Š” ORM์— ๋Œ€ํ•œ ์ดํ•ด

ORM(Object Relational Mapping)์€ RDBMS์˜ ๋ฐ์ดํ„ฐ๋ฅผ OOP(Object Oriented Programming)์˜ Class๋กœ Mapping ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ๋งํ•œ๋‹ค.

[์žฅ์ ]

1. ๊ฐ์ฒด ์ง€ํ–ฅ์ ์ธ ์ฝ”๋“œ๋กœ ์ธํ•ด ๋” ์ง๊ด€์ ์ด๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ๋” ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค€๋‹ค.

  • ORM์„ ์ด์šฉํ•˜๋ฉด SQL Query๊ฐ€ ์•„๋‹Œ ์ง๊ด€์ ์ธ ์ฝ”๋“œ(๋ฉ”์„œ๋“œ)๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์–ด ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐ์ฒด ๋ชจ๋ธ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.
  • ์„ ์–ธ๋ฌธ, ํ• ๋‹น, ์ข…๋ฃŒ ๊ฐ™์€ ๋ถ€์ˆ˜์ ์ธ ์ฝ”๋“œ๊ฐ€ ์—†๊ฑฐ๋‚˜ ๊ธ‰๊ฒฉํžˆ ์ค„์–ด๋“ ๋‹ค.
  • ๊ฐ์ข… ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฝ”๋“œ๋ฅผ ๋ณ„๋„๋กœ ์ž‘์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ์˜ฌ๋ ค์ค€๋‹ค.
  • SQL์˜ ์ ˆ์ฐจ์ ์ด๊ณ  ์ˆœ์ฐจ์ ์ธ ์ ‘๊ทผ์ด ์•„๋‹Œ ๊ฐ์ฒด ์ง€ํ–ฅ์ ์ธ ์ ‘๊ทผ์œผ๋กœ ์ธํ•ด ์ƒ์‚ฐ์„ฑ์ด ์ฆ๊ฐ€ํ•œ๋‹ค.

2. ์žฌ์‚ฌ์šฉ ๋ฐ ์œ ์ง€๋ณด์ˆ˜์˜ ํŽธ๋ฆฌ์„ฑ์ด ์ฆ๊ฐ€ํ•œ๋‹ค.

  • ORM์€ ๋…๋ฆฝ์ ์œผ๋กœ ์ž‘์„ฑ๋˜์–ด์žˆ๊ณ , ํ•ด๋‹น ๊ฐ์ฒด๋“ค์„ ์žฌํ™œ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋•Œ๋ฌธ์— ๋ชจ๋ธ์—์„œ ๊ฐ€๊ณต๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ปจํŠธ๋กค๋Ÿฌ์— ์˜ํ•ด ๋ทฐ์™€ ํ•ฉ์ณ์ง€๋Š” ํ˜•ํƒœ๋กœ ๋””์ž์ธ ํŒจํ„ด์„ ๊ฒฌ๊ณ ํ•˜๊ฒŒ ๋‹ค์ง€๋Š”๋ฐ ์œ ๋ฆฌํ•˜๋‹ค.
  • ๋งคํ•‘์ •๋ณด๊ฐ€ ๋ช…ํ™•ํ•˜์—ฌ, ERD๋ฅผ ๋ณด๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์˜์กด๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ๋‹ค.

3. DBMS์— ๋Œ€ํ•œ ์ข…์†์„ฑ์ด ์ค„์–ด๋“ ๋‹ค.

  • ๊ฐ์ฒด ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ SQL์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— RDBMS์˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์™€ Java์˜ ๊ฐ์ฒด์ง€ํ–ฅ ๋ชจ๋ธ ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ์„ ์ขํž ์ˆ˜ ์žˆ๋‹ค.
  • ๋Œ€๋ถ€๋ถ„ ORM ์†”๋ฃจ์…˜์€ DB์— ์ข…์†์ ์ด์ง€ ์•Š๋‹ค.
  • ์ข…์†์ ์ด์ง€ ์•Š๋‹ค๋Š”๊ฒƒ์€ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฟ๋งŒ์•„๋‹ˆ๋ผ ๋งŽ์€ ์†”๋ฃจ์…˜์—์„œ ์ž๋ฃŒํ˜• ํƒ€์ž…๊นŒ์ง€ ์œ ํšจํ•˜๋‹ค.
  • ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” Object์— ์ง‘์ค‘ํ•จ์œผ๋กœ ๊ทน๋‹จ์ ์œผ๋กœ DBMS๋ฅผ ๊ต์ฒดํ•˜๋Š” ๊ฑฐ๋Œ€ํ•œ ์ž‘์—…์—๋„ ๋น„๊ต์  ์ ์€ ๋ฆฌ์Šคํฌ์™€ ์‹œ๊ฐ„์ด ์†Œ์š”๋œ๋‹ค.
  • ๋˜ํ•œ ์ž๋ฐ”์—์„œ ๊ฐ€๊ณตํ• ๊ฒฝ์šฐ equals, hashCode์˜ ์˜ค๋ฒ„๋ผ์ด๋“œ ๊ฐ™์€ ์ž๋ฐ”์˜ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๊ฐ„๊ฒฐํ•˜๊ณ  ๋น ๋ฅธ ๊ฐ€๊ณต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

[๋‹จ์ ]

1. ์™„๋ฒฝํ•œ ORM ์œผ๋กœ๋งŒ ์„œ๋น„์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค.

  • ์‚ฌ์šฉํ•˜๊ธฐ๋Š” ํŽธํ•˜์ง€๋งŒ ์„ค๊ณ„๋Š” ๋งค์šฐ ์‹ ์ค‘ํ•˜๊ฒŒ ํ•ด์•ผํ•œ๋‹ค.
  • ํ”„๋กœ์ ํŠธ์˜ ๋ณต์žก์„ฑ์ด ์ปค์งˆ๊ฒฝ์šฐ ๋‚œ์ด๋„ ๋˜ํ•œ ์˜ฌ๋ผ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.
  • ์ž˜๋ชป ๊ตฌํ˜„๋œ ๊ฒฝ์šฐ์— ์†๋„ ์ €ํ•˜ ๋ฐ ์‹ฌ๊ฐํ•  ๊ฒฝ์šฐ ์ผ๊ด€์„ฑ์ด ๋ฌด๋„ˆ์ง€๋Š” ๋ฌธ์ œ์ ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.
  • ์ผ๋ถ€ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋Œ€ํ˜• ์ฟผ๋ฆฌ๋Š” ์†๋„๋ฅผ ์œ„ํ•ด SP๋ฅผ ์“ฐ๋Š”๋“ฑ ๋ณ„๋„์˜ ํŠœ๋‹์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.
  • DBMS์˜ ๊ณ ์œ  ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค. (ํ•˜์ง€๋งŒ ์ด๊ฑด ๋‹จ์ ์œผ๋กœ๋งŒ ๋ณผ ์ˆ˜ ์—†๋‹ค : ํŠน์ • DBMS์˜ ๊ณ ์œ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜๋ฉด ์ด์‹์„ฑ์ด ์ €ํ•˜๋œ๋‹ค.)

2. ํ”„๋กœ์‹œ์ €๊ฐ€ ๋งŽ์€ ์‹œ์Šคํ…œ์—์„  ORM์˜ ๊ฐ์ฒด ์ง€ํ–ฅ์ ์ธ ์žฅ์ ์„ ํ™œ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

  • ์ด๋ฏธ ํ”„๋กœ์‹œ์ €๊ฐ€ ๋งŽ์€ ์‹œ์Šคํ…œ์—์„  ๋‹ค์‹œ ๊ฐ์ฒด๋กœ ๋ฐ”๊ฟ”์•ผํ•˜๋ฉฐ, ๊ทธ ๊ณผ์ •์—์„œ ์ƒ์‚ฐ์„ฑ ์ €ํ•˜๋‚˜ ๋ฆฌ์Šคํฌ๊ฐ€ ๋งŽ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

2. Models.py๋กœ Database ์—ฐ๋™

Model.py๋Š” Database ๊ฐ„ ์—ฐ๋™์— ์žˆ์–ด ์‚ฌ์šฉํ•˜๋Š” File ์ด๋‹ค. ์ด๊ณณ์— ์ •์˜๋˜๋Š” Class๋“ค์€ setting.py์˜ DATABASES์— ์ •์˜๋œ ๋Œ€์ƒ Database์— table๋กœ์„œ ์ƒ์„ฑ๋˜๊ฒŒ ๋œ๋‹ค.

class Menu(models.Model):
    name = models.CharField(max_length=45)
class Categories(models.Model):
    name = models.CharField(max_length=45)
    menu = models.ForeignKey(Menu, on_delete=models.CASCADE)
    # FK ์ƒ์„ฑ์‹œ model class๋ฅผ ์ง์ ‘ ๋„ฃ์–ด๋„ ๋˜๊ณ  'app.model'(์—ฌ๊ธฐ์„  services.Menu)๋กœ ์ž…๋ ฅํ•ด๋„ ๋จ.

class Drinks(models.Model):
    category = models.ForeignKey(Categories, on_delete=models.CASCADE)
    korean_name = models.CharField(max_length=45)
    english_name = models.CharField(max_length=45)
    description = models.TextField()    

์œ„ ์ฝ”๋“œ๋Š” Menu, Categories, Drinks์— ๋Œ€ํ•œ class ์ด๋‹ค. ์ด๋ฅผ database๋กœ migrationํ•˜๋ฉด ๊ฐ์ž table์ด ๋œ๋‹ค. ์ฐธ๊ณ ๋กœ table์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Primary key(auto increment)๊ฐ’์œผ๋กœ 'id'๋ฅผ ์ž๋™ ํ• ๋‹นํ•œ๋‹ค. ์œ„์˜ Menu๋ฅผ migration ํ•˜๋ฉด Database์—๋Š” id ์†์„ฑ์ด PK, AI ์„ค์ •์œผ๋กœ ์ž๋™ ์ถ”๊ฐ€๋œ๋‹ค.

๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด Models.py์˜ ๋‚ด์šฉ์„ Database์— ๋ฐ˜์˜ํ• ๊นŒ? ์•„๋ž˜์˜ ๋ช…๋ น์„ ๋ณด์ž

python manage.py makemigrations [Models.py์˜ App ์ด๋ฆ„]

์œ„ ๋ช…๋ น์€ App์„ ๊ธฐ์ค€์œผ๋กœ Database์— ๋ฐ˜์˜ํ•  ๋ณ€๊ฒฝ๋‚ด์šฉ์„ ํ™•์ธ, migrate๋ฅผ ์œ„ํ•œ file์„ ์ค€๋น„ํ•œ๋‹ค. file์€ App/migrations ํด๋”์— py ํ˜•์‹์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค. (ex: 0001_initial.py)

ํŒŒ์ผ์ด ์ค€๋น„๋˜๋ฉด Database๋กœ migrate ํ•œ๋‹ค.

python manage.py migrate

์œ„ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด Database์— ์ตœ์ข… ๋ฐ˜์˜๋œ๋‹ค. ์ฐธ๊ณ ๋กœ ์ค‘๊ฐ„์— Models.py์— ์ •์˜๋œ class์˜ ์ด๋ฆ„์„ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋ฉด migrate ๊ณผ์ •์—์„œ framework๊ฐ€ ์ผ๋ถ€ ์งˆ์˜๋ฅผ ํ• ๋•Œ๊ฐ€ ์žˆ๋‹ค. ๊ฐ€๋ น ์ด๋ฆ„์„ ๋ณ€๊ฒฝ์‹œ ์›๋ณธ์ด ๋ˆ„๊ตฌ์˜€๋Š”์ง€, non-NULL column ์— ๊ฐ’์„ ๊ฐ•์ œ๋กœ ๋„ฃ์–ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์€ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ์ง€ ๋“ฑ์„ ์งˆ์˜ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์•Œ์•„๋‘์ž.

3. table๊ณผ column ์— ๋Œ€ํ•œ CRUD ๋ฐฉ๋ฒ•.

Django๋Š” shell์„ ์ง€์›ํ•œ๋‹ค. shell์„ ํ†ตํ•ด ์‹ค์‹œ๊ฐ„์œผ๋กœ data์— ๋Œ€ํ•œ CRUD ํŠธ๋žœ์žญ์…˜์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

python manage.py shell

์œ„ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด Django ์ œ์–ด๋ฅผ ์œ„ํ•œ shell ์ž…๋ ฅ ๋ชจ๋“œ๋กœ ์ง„์ž…ํ•œ๋‹ค. ์ด๊ณณ์—์„œ python ์ฝ”๋“œ๋ฅผ ๋Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ CRUD ํ•˜๋Š” ๊ณผ์ •์— ๋Œ€ํ•ด ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ฒ ๋‹ค. ์ฐธ๊ณ ๋กœ ๋‚ด๊ฐ€ ์ž‘์—…์ค‘์ธ project๋Š” starbucks, App์€ services ์ด๋‹ค.

  1. Create
from services.Models import *
Menu.objects.create(id=1, name='์Œ๋ฃŒ')

์œ„๋Š” Menu table์— id๋Š” 1, name์€ '์Œ๋ฃŒ'์ธ row๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” Queryset ์ด๋‹ค.

  1. Read
from services.Models import *
Menu.objects.get(id=1)		# id๊ฐ€ 1์ธ ๋‹จ์ผ ๊ฐ’์„ ์–ป์„ ๋•Œ
Menu.objects.filter(id=1)	# id๊ฐ€ 1์ธ list๋ฅผ ์–ป์„ ๋•Œ

์œ„๋Š” Menu table์—์„œ id๋Š” 1, name์€ '์Œ๋ฃŒ'์ธ row๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” Queryset ์ด๋‹ค. ์ด Queryset์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋ฉด '.column'์„ ํ†ตํ•ด ์†์„ฑ๊ฐ’์„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. Update
from services.Models import *
queryset = Menu.objects.get(id=1)
queryset.update(name='์Œ๋ฃŒ')	#๋ฐฉ๋ฒ•1) queryset์—์„œ updateํ•จ์ˆ˜ ์‹คํ–‰
	
    ๋˜๋Š”

queryset.์†์„ฑ = ๊ฐฑ์‹ ๋ฐ์ดํ„ฐ		#๋ฐฉ๋ฒ•2) queryset์— .์œผ๋กœ ์†์„ฑ ์ ‘๊ทผํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๊ฐฑ์‹  ํ›„ Save
queryset.save()

์ฐธ๊ณ ๋กœ Queryset์ด ์—ฌ๋Ÿฌ๊ฐœ์˜ row์ธ ๊ฒฝ์šฐ ์œ„ ๊ณผ์ •์€ ๋ชจ๋“  row์— ์ผ๊ด„ ๋ฐ˜์˜๋œ๋‹ค.

  1. Delete
from services.Models import *
querySet = Menu.objects.get(id=1)
querySet.delete()

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ querySet์ด ์—ฌ๋Ÿฌ๊ฐœ์˜ row๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ผ๊ด„ ์‚ญ์ œ๋œ๋‹ค.

์ด ์™ธ์—๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ธฐ๋Šฅ(SQL์˜ Avg, Max ๊ฐ™์€)์„ querySet์„ ํ†ตํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
querySet ์ฐธ๊ณ  ์‚ฌ์ดํŠธ

profile
12๋…„ .NET ๊ฐœ๋ฐœ ๊ฒฝ๋ ฅ์„ ๊ฐ€์ง„ ์›น ์ดˆ์งœ ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค :)

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