Django Model
์ฅ๊ณ ๋ ORM๊ธฐ๋ฒ์ ๋ฐ๋ผ ํ ์ด๋ธ์ ํ๋์ ํด๋์ค๋ก ์ ์ํ๊ณ , ํ ์ด๋ธ์ ์ปฌ๋ผ์ ํด๋์ค์ ๋ณ์๋ก ๋งคํํ๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์
๊ธฐ๋ณธ์ ์ผ๋ก sqlite3๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค. ๋ง์ฝ์ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด ENGINE์ ๋ท๋ถ๋ถ์ ์์ ํ๋ฉด๋๋ค.
ENGINE
django.db.backends.mysql
django.db.backends.oracle
django.db.backends.postgresql
django.db.backends.sqlite3
NAME
์ฌ๊ธฐ์ name์ ํ๋ก์ ํธ ์ ์ฅ๋ ํ์ผ ๋ช ์ด๋ค.
์ฌ์ฉ์ ์ค์
SQLite ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ USER, PASSWORD, HOST๋ฅผ ์ถ๊ฐ ์ค์ ํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
๋ชจ๋ธ ๋ง๋ค๊ธฐ
๊ฐ ๋ชจ๋ธ์ Django.db.models.Model
ํด๋์ค์ ์๋ธํด๋์ค๋ก ํํ๋๋ค. ๊ฐ๊ฐ์ ๋ชจ๋ธ์ ์ฌ๋ฌ๊ฐ์ ํด๋์ค ๋ณ์(๋ชจ๋ธ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋)๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
models๋ ์์ฑํ ๋ชจ๋ธ์ด ์ฅ๊ณ ๋ชจ๋ธ์์ ์๋ฏธํ๋ค. ์ฅ๊ณ ๋ ์์ฑ๋ model์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋์ด์ผํ๋ค๊ณ ์๊ฒ๋๋ค.
์๋์์ ๊ฐ๋จํ ์์๋ฅผ ์ดํด๋ณด์.
์ค๋ฌธ์กฐ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ Question๊ณผ Choice ๋๊ฐ์ ๋ชจ๋ธ์ ์์ฑํด๋ณด์. ์ด๋ ๋๊ฐ์ ๋ชจ๋ธ์ ์ฐ๊ด๋์ด ์๋ค.
์์ฑ(Field)
๋ชจ๋ธ์ ์ฌ๋ฌ๊ฐ์ ์์ฑ์ ๊ฐ์ง๊ณ ์๋ค. ์์ฑ์ ์ ์ํ๊ธฐ ์ํด์๋ ๊ฐ ํ๋๋ง๋ค ์ด๋ค ์ข ๋ฅ์ ๋ฐ์ดํฐ ํ์ (ํ ์คํธ, ์ซ์, ๋ ์ง, ๋ค๋ฅธ ๊ฐ์ฒด ์ฐธ์กฐ ๋ฑ)์ ๊ฐ์ง๋์ง๋ฅผ ์ ํด์ผํ๋ค.
๊ฐ ์์ฑ์ Field
ํด๋์ค์ ์ธ์คํด์ค๋ก ํํ๋๋ค.
Field
์ค๋ช
AutoField(**options)
id๋ก ์ฌ์ฉ ๊ฐ๋ฅํ ์๋์ผ๋ก ์ฆ๊ฐํ๋ IntegerField์ด๋ค. ๋ชจ๋ธ์ ๊ธฐ๋ณธํค ํ๋๋ฅผ ๋ณ๋๋ก ์ง์ ํ์ง ์์ผ๋ฉด ์๋์ผ๋ก ์ถ๊ฐ๋๋ค.
BooleanField(**options)
true / false ํ๋์ด๋ค. null๊ฐ ํ์ฉ์ด ํ์ํ๋ค๋ฉด NullBooleanField ๋ฅผ ์ฌ์ฉํ๋ฉด๋๋ค. Default ์ต์ ์ ์ ์ํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ์ None์ด๋ค.
CharField(max_length=None,**options)
๊ธ์์๊ฐ ์ ํ๋ ํ
์คํธ๋ฅผ ์ ์
์ ๋ชฉ๊ณผ ๊ฐ์ด ์งง์ ๋ฌธ์์ด ์ ๋ณด๋ฅผ ์ ์ฅํ ๋ ์ฌ์ฉํ๋ค.
max_length
ํ๋์ ์ต๋๊ธธ์ด๋ ํ์ ์ต์
์ด๋ค.
DecimalField(max_digit=None, decimal_palces=None, **options)
๊ณ ์ ์์๋ก Python์ Decimal ์ธ์คํด์ค๋ก ๋ํ๋๋ค.
max_digits
์ซ์์ ํ์ฉ๋๋ ์ต๋ ์๋ฆฟ์์ด๋ค.
decimal_palces
์ซ์์ ํจ๊ป ์ ์ฅ๋ ์์ ์๋ฆฟ์์ด๋ค.
DecimalField(โฆ, max_digits=5, decimal_palces=2) ๋ ์ต๋ 999 ์์์ 2์๋ฆฌ ์ดํ์ด๋ค.
IntegerField(**options)
์ ์ ๊ฐ
TextField(**options)
๊ธ์ ์์ ์ ํ์ด ์๋ ๊ธด ํ ์คํธ๋ฅผ ํํํ๋ค.
DateTimeField(auto_now=False, auto_now_add=False,**options)
๋ ์ง์ ์๊ฐ์ ์ ์ํ๋ค.
auto_now
๋ ๊ฐ์ฒด๊ฐ ์ ์ฅ๋ ๋๋ง๋ค ๋งค๋ฒ ์๋์ผ๋ก ํ์ฌ์๊ฐ์ด ์ค์ ๋๋ค.( ์ต๊ทผ ์์ ๋ฑ timestamp๋ก์จ ์ ์ฉํ๋ค.) Model.save
๊ฐ ํธ์ถ๋ ๋ ์๋์ผ๋ก ์์ ๋๋ค.
auto_now_add
๊ฐ์ฒด๊ฐ ์ฒ์ ์์ฑ๋ ๋ ์๋์ผ๋ก ํ์ฌ์๊ฐ์ด ์ค์ ๋๋ค. (์์ฑ์ timestamp๋ก ์ ์ฉ) ๋ง์ฝ ์์ ์ ์ํ๋ค๋ฉด default=today
or default=tiemzone.now
๋ฅผ ์ฌ์ฉํ๋ฉด๋๋ค.
์ด 3๊ฐ์ ์ต์
์ ๊ฐ์ด ์ธ ์ ์์ผ๋ฉฐ, ๋ง์ฝ auto ์ต์
์ True๋ก ์ค์ ํ๋ฉด editable=False, blank=True ๋ก ์ค์ ๋๋ค.
ForeignKey(**options)
๋ค๋ฅธ ๋ชจ๋ธ ์ฐธ์กฐํค์ด๋ค.
models.ForeignKey(Question, on_delete=models.CASCADE)
์์๋ ๊ฐ๊ฐ์ Choice๊ฐ ํ๋์ Question์ ๊ด๊ณ๋๋ค๋ ๊ฒ์ ์๋ ค์ค๋ค.
FilePathField(path=None, match=None, recursive=False, max_length=100, **options)
ํ์ผ ์์คํ
์์ ํน์ ํ ๋๋ ํฐ๋ฆฌ์ ํ์ผ์ด๋ฆ์ผ๋ก ์ ํ๋๋ค.
path
๋ ํ์ ์ธ์๋ก ์ ๋ ํ์ผ ์์คํ
๊ฒฝ๋ก์ด๋ค.(/home/images
)
match
: ์ ํ์ ์ธ์๋ก ํ์ผ ์ด๋ฆ์ ํํฐ๋งํ ๋ ์ฌ์ฉํ ๋ฌธ์์ด๋ก ๋ ์ ๊ทํํ์์ด๋ค. ๊ธฐ๋ณธํ์ผ ์ด๋ฆ์ ์ ์ฉ๋๋ค. (foo.*\.txt$
)
recursive
: ์ ํ์ ์ธ์๋ก path์ ๋ชจ๋ ์๋ธ ๋๋ ํฐ๋ฆฌ๊ฐ ํฌํจ๋์ผํ๋์ง ์ฌ๋ถ๋ฅผ ์ง์ (true/false)
allow_files
or allow_folders
: ์ ํ์ ์ธ์๋ก ์ง์ ๋ ์์น์ ํ์ผ or ํด๋๋ฅผ ํฌํจํ ์ง ์ฌ๋ถ๋ฅผ ์ง์ ํ๋ค(true/false). ๋ ์ค ํ๊ฐ๋ ๋ฐ๋์ True์ฌ์ผํ๋ค.
๋ชจ๋ธ ๊ด๊ณ
One-to-One
ํ ํ ์ด๋ธ์ ํ๋์ ๋ ์ฝ๋๊ฐ ๋ค๋ฅธ ํ ์ด๋ธ์ ๋จ ํ๋์ ๋ ์ฝ๋๋ง์ ์ฐธ์กฐํ ๋, ์ด ๋ ๋ชจ๋ธ๊ฐ์ ๊ด๊ณ๋ฅผ ์ผ๋์ผ ๊ด๊ณ๋ผ๊ณ ํ๋ค.
์์ ๊ฐ์ด ๊ฐ์ธ ๊ณ ๊ฐ ํ๋ช ๋น ์ฌ๊ถ์ ํ๊ฐ ์์ ์ ์๋ค.
OneToOneField
OneToOneField
๋ ForeignKey
ํ๋์ unique=Ture
์ต์
์ ์ค ๊ฒ๊ณผ ๋์ผํ๊ฒ ๋์ํ๋ค. ์ฆ, ForeignKye ๊ฐ์ด ๋ฐ๋์ ๊ณ ์ ํ ๊ฐ์ด์ด์ผํ๋ค.
์์๋ฅผ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
์ผ๋์ผ ๊ด๊ณ์์ ํ ๋ชจ๋ธ์ด ๋ค๋ฅธ ๋ชจ๋ธ์ ์ฐธ์กฐํ๋ ๋ฐฉ๋ฒ์ด๋ค.
Many-to-One
ํ ํ ์ด๋ธ์ ์๋ ๋ ๊ฐ ์ด์์ ๋ ์ฝ๋๊ฐ ๋ค๋ฅธ ํ ์ด๋ธ์ ์๋ ํ๋์ ๋ ์ฝ๋๋ฅผ ์ฐธ์กฐํ๋ ๊ฒฝ์ฐ์ด๋ค.
๋ค์๊ณผ ๊ฐ์ด ForeignKey๋ฅผ ์ด์ฉํด์ ๋ค๋์ผ ๊ด๊ณ๋ฅผ ์ค์ ํ ์ ์๋ค. ํ ๊ณ ๊ฐ์ด ์ฃผ๋ฌธ์ ์ฌ๋ฌ๊ฐ ํ ์ ์๋ ๊ฒฝ์ฐ์ ๋ํด์ ์ดํด๋ณด์
์ฌ๊ธฐ์ ForeignKey์ ํ๋๋ช ์ ์์ ๋กญ๊ฒ ํ ์ ์์ง๋ง ์ฐ๊ฒฐ๋์ ๋ชจ๋ธ์ ์๋ฌธ์๋ก ์ ํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค.
on_delete
์ต์
์ค๋ช
CASCADE
๋ ์ฝ๋๊ฐ ์ญ์ ๋๋ฉด, ๊ทธ ๋ ์ฝ๋๋ฅผ ์ธ๋ํค๋ก ์ฐธ์กฐํ๊ณ ์๋ ๋ชจ๋ ๋ ์ฝ๋๋ฅผ ํจ๊ป ์ญ์ ํ๋ค.(default)
PROTECT
์ธ๋ํค๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ๋ ์ฝ๋๋ฅผ ์ญ์ ํ์ง ๋ชปํ๊ฒ ๋ง๋ ๋ค. ์ญ์ ๋ฅผ ์๋ํ๋ ๊ฒฝ์ฐ ProtectedError๊ฐ ๋ฐ์ํ๋ค.
SET_NULL
์ธ๋ํค๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ๋ ์ฝ๋๊ฐ ์ญ์ ๋๋ฉด, ์ธ๋ํค ํ๋ ๊ฐ์ด null
๊ฐ์ด ๋๋ค. ์ด๋ ์ธ๋ํค ํ๋์ null=True
์ต์
์ด ์์ ๋๋ง ๊ฐ๋ฅํ๋ค.
SET_DEFAULT
์ธ๋ํค๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ๋ ์ฝ๋๊ฐ ์ญ์ ๋๋ฉด, ์ธ๋ํค ํ๋์ ๊ฐ์ด ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ฐ๋๋ค. (default
์ต์
์ด ์ค์ ๋์ด ์์ ๋๋ง ๊ฐ๋ฅํ๋ค.)
SET()
SET()
ํจ์์ ๊ฐ์ด๋ ํธ์ถ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ์ ์๋ค. ์ธ๋ํค๊ฐ ์ฐธ์กฐํ๋ ๋ ์ฝ๋๊ฐ ์ญ์ ๋๋ฉด ์ ๋ฌ๋ ๊ฐ ๋๋ ๊ฐ์ฒด๋ฅผ ํธ์ถํ ๊ฒฐ๊ณผ๋ก ์ธ๋ํค๋ฅผ ์ฑ์ด๋ค.
์ฌ๊ท์ ๊ด๊ณ(Recursive)
ํ ํ ์ด๋ธ์ ๋ ์ฝ๋๋ค์ด ๊ฐ์ ํ ์ด๋ธ์ ๋ค๋ฅธ ๋ ์ฝ๋๋ค๊ณผ ๊ด๊ณ๋ฅผ ํ์ฑํ๋ ๊ฒ์ ๋งํ๋ค.
์๋ฅผ ๋ค์๋ฉด, ๊ฐ์ ์คํฐ๋์์ ํ๋ช ์ด ๋ค๋ฅธ ์คํฐ๋์์ ๊ด๋ฆฌํ๋ ๊ฒฝ์ฐ๋ฅผ ์๋ก ๋ค์์๋ค.
ID
Name
Tutor_ID
1
Joe Satriani
1
2
John Petrucci
1
3
Steve Vai
1
๋ค์๊ณผ ๊ฐ์ด 'self'
๋ฅผ ์ ๋ฌํ์ฌ ์ค์ ํ ์ ์๋ค.
์ ์๋์ง ์์ ํ
์ด๋ธ๊ณผ์ ๊ด๊ณ
๋ชจ๋ธ์ ์์ฑํ ๋ ์์ง ์ ์๋์ง ์์ ํ
์ด๋ธ๊ณผ์ ๊ด๊ณ๋ฅผ ์ค์ ํด์ผํ๋ ๊ฒฝ์ฐ์๋ '๋ชจ๋ธ๋ช
'
์ ์ ๋ฌํ๋ฉด๋๋ค.
Many-to-Many
ํ๋์ ํ ์ด๋ธ์ ํ๋ ์ด์์ ๋ ์ฝ๋๊ฐ ๋ค๋ฅธ ํ ์ด๋ธ์ ํ๋ ์ด์์ ๋ ์ฝ๋๋ฅผ ์ฐธ์กฐํ๋ ๊ฒฝ์ฐ์ด๋ค. ๋ค๋๋ค ๊ด๊ณ๋ฅผ ํํํ ๋, ๋ ํ ์ด๋ธ ์ฌ์ด์ ๊ด๊ณ๋ฅผ ํํํ๊ธฐ ์ํด ์ฐธ์กฐ ์ ๋ณด๋ฅผ ๋ด์ ์๋ก์ด ํ ์ด๋ธ(์ค๊ฐ๋ชจ๋ธ)์ ์์ฑํ๊ฒ ๋๋ค.
ManyToManyField
๋ฅผ์ด์ฉํด์ ์ค์ ํ ์ ์๋ค.
ManyToManyField
๋ค๋๋ค ๊ด๊ณ์ ํ๋๋ช ์ ๋ณต์ํ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค.
์๋ก ๊ด๊ณ๋ ๋ชจ๋ธ๋ค ์ค ์ด๋ ๊ณณ์ ModelToManyField๋ฅผ ์ ์ธํ๋ ์๊ด ์์ง๋ง ํ ๋ชจ๋ธ์๋ง ์ ์ธํด์ผํ๋ฉฐ, ์๋ฏธ๊ฐ ์์ฐ์ค๋ก์ด ๊ณณ์ ์ ์ธํด์ฃผ๋ ๊ฒ์ ๊ถ์ฅํ๋ค.
์ค๊ฐ๋ชจ๋ธ(Intermediary Model)
๋ ํ
์ด๋ธ์ ๋ค๋๋ค ๊ด๊ณ๋ฅผ ๋ํ๋ด์ฃผ๋ ๋ชจ๋ธ์ด๋ค. ๋ ๋ชจ๋ธ์ ์ธ๋ํค๋ฅผ ํ๋๋ก ๊ฐ์ง๊ณ ์๋ค. ManyToManyField
๋ก ๊ด๊ณ์ค์ ํ๋ฉด ์๋์ผ๋ก ์์ฑ๋์ง๋ง ์ง์ ์์ฑํ ์๋ ์๋ค.
- though
- through_field
์ค๊ฐ ๋ชจ๋ธ์ ์ง์ ์์ฑํ๋ ๊ฒฝ์ฐ์ ๋ ํ ์ด๋ธ์ ์ฐธ์กฐํ๋ ์ธ๋ํค ํ๋๋ฅผ ๋ช ํํ ์ ์ธํด์ผํ๋ค.
์์ค๋ชจ๋ธ(Source Model) :
ManyToManyField
๊ฐ ์๋ ๋ชจ๋ธ์ ๋งํ๋ค.ํ๊ฒ๋ชจ๋ธ(Target Model) :
ManyToManyField
์ ์ธ์๋ก ์ ๋ฌ๋๋ ๋ชจ๋ธ์ ๋งํ๋ค.
๋ง์ฝ ์ค๊ฐ ๋ชจ๋ธ์์ ํ๋ ์ด์์ ์ธ๋ํค ํ๋๊ฐ ์์ค ๋ชจ๋ธ ํน์ ํ๊ฒ ๋ชจ๋ธ์ ์ฐธ์กฐํ๋ค๋ฉด, through_field
์ต์
์ ํตํด ์ธ๋ํค ์ค์ ์ ํด์ค์ผํ๋ค.
์ญ์ฐธ์กฐ
์ธ๋ํค ํ๋๋ฅผ ๊ฐ์ง ์์ค๋ชจ๋ธ์ ์ฐ๊ฒฐ๋ ํ๊ฒ๋ชจ๋ธ์ ์ธ์คํด์ค๋ค์ ์์ ๊ณผ ์ฐ๊ฒฐ๋ ์์ค๋ชจ๋ธ์ ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ Manager
๋ฅผ ๊ฐ์ง๊ฒ๋๋ค. Manager๋ ์์ค๋ชจ๋ธ๋ช
_set
์ ํํ๋ก ์์ฑ๋๋ค. Reverse accessor๋ ๊ด๊ณ๋ฅผ ์ญ์ฐธ์กฐํ ์ ์๋ ์ด Manger๋ฅผ ์๋ฏธํ๋ค.
- related_name
์๋์ผ๋ก ์์ฑ๋๋ ์ญ์ฐธ์กฐ Manger์ด๋ฆ์ related_name
์ต์
์ผ๋ก ๋ฐ๊ฟ์ค ์ ์๋ค.
๋ชจ๋ธ ํ์ฑํ
makemigrations
makemigartions
๋ช
๋ น์ด๋ฅผ ์คํํด ๋ชจ๋ธ์ ์์ฑ, ๋ณ๊ฒฝ๋ ์ฌํญ์ migration ์ผ๋ก ์ ์ฅํ๋ ๋ช
๋ น์ด์ด๋ค.
Migration
๋ชจ๋ธ์ ๋ณ๊ฒฝ์ฌํญ์ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ผ๋ก, ๋์คํฌ์์ ํ์ผ๋ก ์กด์ฌํ๋ค.
์์ฑ๋ migration๋ค์ ์คํ์์ผ์ฃผ๊ณ , ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง๋ฅผ ๊ด๋ฆฌํด์ฃผ๋ migrate
๋ช
๋ น์ด๊ฐ ์๋ค.
sqlmigrate
migration์ ์ด๋ฆ์ ์ธ์๋ก ๋ฐ์์ ์คํํ๋ SQL๋ฌธ์ ๋ณผ ์ ์๋ค. ํ์ง๋ง ์ค์ ๋ก migration์ ์คํํ์ง๋ ์๋๋ค. ๋จ์ํ ๊ฒฐ๊ณผ๋ง ์ถ๋ ฅํ ๋ฟ์ด๋ค.
migrate
์์ง ์ ์ฉ๋์ง ์์ ๋ชจ๋ migration์ ์์งํด ์คํํ๋ค. django_migrations
ํ
์ด๋ธ์ ๋ง์ด๊ทธ๋ ์ด์
์ ์ฉ ์ฌ๋ถ๋ฅผ ๊ธฐ๋กํ๋ค.
Python Shell๋ก ๋ชจ๋ธ ๋ค๋ค๋ณด๊ธฐ
shell ์คํํ๊ธฐ
manage.py ๋ฅผ ํตํด์ shell์ ์คํํ๊ฒ ๋๋ฉด Django์์ ๋์ํ๋ ๋ชจ๋ ๋ช ๋ น์ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๋ค.
Imort Model
๊ฐ์ฒด ์กฐํํ๊ธฐ
__str__
๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ฒด์ ๋ํ ์ค๋ช
์ __str__()
๋ฅผ ์ถ๊ฐํ์ฌ ๋ฐ๊ฟ ์ ์๋ค.
๊ฐ์ฒด ์์ฑํ๊ธฐ
ํํฐ๋งํ๊ธฐ
๋ฐ์ดํฐ๋ฅผ ํํฐ๋ง ํ๋ ๊ฒ์ ์ค์ํ ๋ถ๋ถ์ด๋ค. ํํฐ๋ง์ ํตํด์ ์ํ๋ ๋ฐ์ดํฐ๋ง ๊ฐ์ ธ์ฌ ์ ์๋ค.
ํํฐ๋ง์ ๊ด๋ จํด์๋ ๊ณต์ ๋ ํผ๋ฐ์ค๋ฅผ ์ฐธ์กฐํ๋ฉด๋๋ค.
๋ค๋ฅธ ๋ชจ๋ธ๊ณผ ์ฐ๊ฒฐํ๊ธฐ
order_by : ์ ๋ ฌํ๊ธฐ
๋ชจ๋ธ์ ์์ฑ์ ๋ฐ๋ผ ์ ๋ ฌํ๊ธฐ ์ํด์ ์ฌ์ฉํ ์ ์๋ค.
์์ฑ๋ช
์ -
๊ฐ ๋ถ์ผ๋ฉด ๋ด๋ฆผ์ฐจ์์ด๋ค.
์ฐธ์กฐ
Model Field https://brunch.co.kr/@ddangdol/4
์ฅ๊ณ ๋ชจ๋ธ ๊ด๊ณ https://nachwon.github.io/django-relationship/
Last updated