1. Django Tutorial(Airbnb) - Custom User Model

ID์งฑ์žฌยท2021๋…„ 7์›” 26์ผ
0

Django

๋ชฉ๋ก ๋ณด๊ธฐ
9/43
post-thumbnail

๐ŸŒˆ Custom User Model

๐Ÿ”ฅ Substituting a custom User model

๐Ÿ”ฅ Model field


1. Django custom User model

1) createsuperuser

  • admins site(http://127.0.0.1:8000/admin)๋กœ ์ ‘๊ทผํ•˜๋ฉด Admin Site์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋กœ๊ทธ์ธ์ฐฝ์ด ๋‚˜ํƒ€๋‚˜๋Š”๋ฐ์š”,, console ๋ช…๋ น์„ ํ†ตํ•ด ๊ด€๋ฆฌ์ž ๊ณ„์ •(superuser)์„ ์ƒ์„ฑ ํ›„ ๋กœ๊ทธ์ธ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • ๐Ÿ”Ž python manage.py createsuperuser
  • ๋ช…๋ น์œผ๋กœ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ด€๋ฆฌ์ž ๊ณ„์ •์„ ์ƒ์„ฑ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์€ Django๊ฐ€ ์ด๋ฏธ User ๋ชจ๋ธ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์—์š”. ๋”ฐ๋ผ์„œ Django๊ฐ€ ์ด๋ฏธ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” User ๋ชจ๋ธ("AbstractUser")์„ ์ƒ์†๋ฐ›๊ณ  ์ด๋ฅผ ํ™•์žฅ์‹œ์ผœ ์‚ฌ์šฉํ•ด๋ณผ๊ป˜์š”.
  • Django๊ฐ€ ๊ฐ€์ง„ User ๋ชจ๋ธ์— ์ถ”๊ฐ€๋กœ ํ•„๋“œ๋ฅผ ํ™•์žฅ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ settgins.py์˜ ์„ค์ •์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ช…์‹œํ•ด ์ฃผ์–ด์•ผํ•ด์š”. ์ด๋ฅผ "Substituting a custom User model"๋ผ ํ•ฉ๋‹ˆ๋‹ค.
# settings.py
# Custom User Model
AUTH_USER_MODEL = "users.User" # ๐Ÿ‘ˆ users์•ฑ์˜ "User" Model์„ ํ™•์žฅ์— ์‚ฌ์šฉํ• ๊บผ์—์š”:)

2) models.py

  • settgins.py์˜ ์„ค์ •์„ ํ†ตํ•ด Django์˜ ๋ชจ๋ธ์„ ์ƒ์†๋ฐ›๊ธฐ๋กœ ์„ค์ •ํ•˜์˜€๋‹ค๋ฉด, models.py์—์„œ "AbstractUser"๋ฅผ ์ƒ์† ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค.
from django.contrib.auth.models import AbstractUser # ๐Ÿ‘ˆ AbstractUser๋ฅผ import
from django.db import models
class User(AbstractUser):
    pass
  • ํ˜น์‹œ, ์ด๋ฏธ superuser๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌ์ž ๊ณ„์ •์„ ์ƒ์„ฑํ•˜์˜€๊ฑฐ๋‚˜, Model์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜์—ฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค๋ฉด, DB๋ฅผ ์ดˆ๊ธฐํ™”์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ "db.sqlite3"๋ฅผ ์ง€์šฐ๊ณ  migration ์‹œ์ผœ์ฃผ์„ธ์š”!
    • ๐Ÿ”Ž "db.sqlite3" ์‚ญ์ œ
    • ๐Ÿ”Ž python manage.py makemigrations && python manage.py migrate

3) admin.py

  • ์ƒ์„ฑํ•œ Model์„ Admin Site์—์„œ ๋‚˜ํƒ€๋‚˜๊ฒŒ ํ•˜๋ ค๋ฉด,, Model์„ admin.py์— ๋“ฑ๋ก์‹œ์ผœ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.
from django.contrib import admin
from . import models # ๐Ÿ‘ˆ ํ•ด๋‹น model์ด ์กด์žฌํ•˜๋Š” ํŒŒ์ผ์„ import
@admin.register(models.User) # ๐Ÿ‘ˆ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ๋“ฑ๋ก
class CustomUserAdmin(admin.ModelAdmin):
    pass


2. Model field

1) ImageField()

  • ImageField๋Š” ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์ €์žฅํ•˜๋Š” ํ•„๋“œ์—์š”,, ์•„๋ž˜ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜ํƒ€๋‚œ๋‹ค๋ฉด "pillow"๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค:)
  • "pillow" ์„ค์น˜ ๋ฐฉ๋ฒ• : ๐Ÿ”Ž pipenv install pillow

2) CharField() & TextField()

  • CharField๋Š” ์„ฑ๋ณ„, ์ œ๋ชฉ, ์ด๋ฆ„ ๋“ฑ ์งง์€ Text๋ฅผ ์œ„ํ•œ Field์ด๊ณ , TextField๋Š” ์†Œ๊ฐœ, ์„ค๋ช… ๋“ฑ ๊ธด ๋ฌธ์žฅ์„ ์ €์žฅํ•˜๋Š” Field๊ฐ€ ํ•„์š”์ž…๋‹ˆ๋‹ค.
  • max_length ์†์„ฑ
    • CharField์—์„œ๋Š” ํ…์ŠคํŠธ์˜ ๊ธธ์ด๋ฅผ ์ œํ•œํ•˜๊ธฐ ์œ„ํ•ด max_length ์†์„ฑ์„ ํ•ญ์ƒ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.
  • null ์†์„ฑ
    • null์€ ๋นˆ๊ฐ’์„ DB์— ํ—ˆ์šฉํ•˜์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์†์„ฑ์œผ๋กœ default๋กœ "null=False"๊ฐ€ ์ ์šฉ๋˜์–ด ์žˆ์œผ๋‚˜, "null=True"๋กœ ์ง€์ •ํ•˜๋ฉด, DB์— ๋นˆ๊ฐ’์„ ํ—ˆ์šฉ์‹œํ‚ต๋‹ˆ๋‹ค.
  • console์— ์•„๋ž˜์ฒ˜๋Ÿผ ๋‚˜ํƒ€๋‚œ ๊ฒƒ์€ ๊ธฐ์กด์— ์ด๋ฏธ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ๋Š” ์–ด๋–ป๊ฒŒ ํ• ๊ฑด์ง€์— ๋Œ€ํ•ด ๋ฌผ์–ด๋ณด๋Š” ๊ฑฐ์—์š”:) 1๋ฒˆ์€ console์—์„œ ์ฒ˜๋ฆฌํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๊ณ , 2๋ฒˆ์€ ํ˜„์žฌ ๋ช…๋ น์„ ์ทจ์†Œํ•˜๊ณ  ์—๋””ํ„ฐ์—์„œ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.
  • default ์˜ต์…˜
    • default๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด DB์— ํ•„๋“œ๊ฐ€ ๋น„์–ด์žˆ์„ ๊ฒฝ์šฐ, ํ•„๋“œ๊ฐ’์„ null๋กœ ๋‘๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ default๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์–ด์š”. default๋ฅผ ํ†ตํ•ด ์ด๋ฏธ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ์˜ ํ•ด๋‹น ํ•„๋“œ๊ฐ’์„ ""์˜ ๋‚ด์šฉ์œผ๋กœ ์ฑ„์›Œ์ค„ ์ˆ˜ ์žˆ์–ด์š”!
  • blank ์†์„ฑ
    • blank๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Admin Panel ์ƒ์˜ ๋นˆ ๊ฐ’์„ ํ—ˆ์šฉ์‹œํ‚ฌ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์–ด์š”. default๋กœ๋Š” "blank=False"์ด๋ฉฐ, "blank=True"๋กœ ์ง€์ •ํ•˜๋ฉด Admin Site ์ƒ์—์„œ form์˜ ๋นˆ๊ฐ’์„ ํ—ˆ์šฉ์‹œํ‚ต๋‹ˆ๋‹ค. ์ด์— "blank=True" ์ง€์ •ํ•˜๋ฉด Admin Panel์— "This field is required" ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์š”!
  • ์ƒˆ๋กœ์šด ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€๊ฑฐ๋‚˜, ํ•„๋“œ๊ฐ€ ์ˆ˜์ •๋˜์—ˆ๋‹ค๋ฉด migrate๋กœ ์ง„ํ–‰ํ•ด์ฃผ์–ด์•ผ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค:)
    • ๐Ÿ”Ž python manage.py makemigrations โ†’ python manage.py migrate
  • choices ์†์„ฑ
    • choices ์˜ต์…˜์€ CharField ํ•„๋“œ์—์„œ ์„ ํƒ ๋ชฉ๋ก์„ ์ œ๊ณตํ•ด ์ค๋‹ˆ๋‹ค. ์„ ํƒ ๋ชฉ๋ก์„ ์ƒ์ˆ˜๋กœ ๋งŒ๋“ค์–ด choices์˜ ๊ฐ’์œผ๋กœ ์ง€์ •ํ•˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ์„ ํƒ ๋ชฉ๋ก์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ์ด ์†์„ฑ์€ ํ•„๋“œ์˜ form ์–‘์‹์„ customํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— migrate๋ฅผ ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ์ ์šฉ๋˜์š”:)
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
    """Custom User Model"""
    GENDER_MALE = "male"  # ๐Ÿ‘ˆ "male"์€ DB์— ์ €์žฅ๋  ๊ฐ’
    GENDER_FEMALE = "female"  
    GENDER_OTHER = "other"  
    GENDER_CHOICES = (
        (GENDER_MALE, "Male"),  # ๐Ÿ‘ˆ "Male"์€ admin์— ํ‘œ์‹œ๋˜๋Š” ๊ฐ’
        (GENDER_FEMALE, "Female"), 
        (GENDER_OTHER, "Other"), 
    )
    LANGUAGE_ENGLISH = "en" # ๐Ÿ‘ˆ "en"์€ DB์— ์ €์žฅ๋  ๊ฐ’
    LANGUAGE_KOREAN = "kr"
    LANGUAGE_CHOICES = (
        (LANGUAGE_ENGLISH, "English"), # ๐Ÿ‘ˆ "English"๋Š” admin์— ํ‘œ์‹œ๋˜๋Š” ๊ฐ’
        (LANGUAGE_KOREAN, "Korean"),
    )
    avatar = models.ImageField(null=True, blank=True)
    gender = models.CharField(choices=GENDER_CHOICES, max_length=10, null=True, blank=Tru)
    bio = models.TextField(default="", blank=True)
    language = models.CharField(choices=LANGUAGE_CHOICES, max_length=2)

3) DateTimeField() vs DataField()

  • DateTimeField๋Š” ๋‚ ์งœ์™€ ์‹œ๊ฐ„๊นŒ์ง€ ์ž…๋ ฅ์„ ์ œ๊ณตํ•˜๋Š” ํ•„๋“œ์ด๋ฉฐ, DateField ๋‚ ์งœ๋งŒ ์ž…๋ ฅ์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ๐Ÿ”Ž birthdate = models.DateField(null=True)
  • ์˜ต์…˜์œผ๋กœ๋Š” "auto_now"์™€ "auto_now_add"๊ฐ€ ๋Œ€ํ‘œ์ ์ž…๋‹ˆ๋‹ค.
    • auto_now : Model์˜ Object๊ฐ€ ์ €์žฅ๋  ๋•Œ๋งˆ๋‹ค ๊ฐ’์„ ๊ฐฑ์‹ 
    • auto_now_add : Model์— Object๊ฐ€ ์ตœ์ดˆ ์ €์žฅ ๋•Œ๋งŒ ๊ฐ’์„ ์ €์žฅ

4) BooleanField

  • BooleanField๋Š” False์™€ True๊ฐ’๋งŒ ์ €์žฅํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Field์ด๋ฉฐ, ์ผ๋ฐ˜์ ์œผ๋กœ default ์˜ต์…˜๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • ๐Ÿ”Ž superhost = models.BooleanField(default=False)
from django.contrib.auth.models import AbstractUser
from django.db import models
# Create your models here.
class User(AbstractUser):
    """Custom User Model"""
    GENDER_MALE = "male"
    GENDER_FEMALE = "female"
    GENDER_OTHER = "other"
    GENDER_CHOICES = (
        (GENDER_MALE, "Male"),
        (GENDER_FEMALE, "Female"),
        (GENDER_OTHER, "Other"),
    )
    LANGUAGE_ENGLISH = "en"
    LANGUAGE_KOREAN = "kr"
    LANGUAGE_CHOICES = (
        (LANGUAGE_ENGLISH, "English"),
        (LANGUAGE_KOREAN, "Korean"),
    )
    CURRENCY_USD = "usd"
    CURRENCY_KRW = "krw"
    CURRENCY_CHOICES = (
        (CURRENCY_USD, "USD"),
        (CURRENCY_KRW, "KRW"),
    )
    avatar = models.ImageField(null=True, blank=True)
    gender = models.CharField(
        choices=GENDER_CHOICES, max_length=10, null=True, blank=True
    )
    bio = models.TextField(default="", blank=True)
    birthdate = models.DateField(null=True)
    language = models.CharField(
        choices=LANGUAGE_CHOICES, max_length=2, null=True, blank=True
    )
    currency = models.CharField(
        choices=CURRENCY_CHOICES, max_length=3, null=True, blank=True
    )
    superhost = models.BooleanField(default=False)

  • Birthdate๋งŒ Bold๊ฐ€ ์ ์šฉ๋˜์—ˆ๋Š”๋ฐ, ์ด๋Š” blank=False์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ฆ‰, Admin Site์—์„œ ๋นˆ๊ฐ’์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด์ฃ . ์ด ์ฒ˜๋Ÿผ ๋ฐ˜๋“œ์‹œ ์ž…๋ ฅํ•ด์•ผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ํ•„๋“œ๋Š” Bold๊ฐ€ ์ ์šฉ๋˜ ์žˆ์Šต๋‹ˆ๋‹ค:)
profile
Keep Going, Keep Coding!

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