Search

Django CharField blank or null?

Intro

Django λͺ¨λΈ 클래슀의 λ¬Έμžμ—΄ 기반 ν•„λ“œμ— blank λ˜λŠ” null μ˜΅μ…˜μ„ μ§€μ •ν•˜λŠ” 쑰건에 λŒ€ν•΄ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

Known Fact

처음 Djangoλ₯Ό μ ‘ν•˜κ³  Django κ΄€λ ¨ λ‚΄μš©μ„ 검색 ν•˜λ‹€λ³΄λ©΄, Vitor Freitas의 SimpleIsBetterThanComplexλΌλŠ” λΈ”λ‘œκ·Έλ₯Ό 자주 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
μ΄ˆλ³΄μžλ“€μ—κ²Œ μœ μš©ν•œ λ‚΄μš©μ΄ λ§Žμ€ 맀우 쒋은 λΈ”λ‘œκ·Έμž…λ‹ˆλ‹€.
μœ„ λΈ”λ‘œκ·Έμ— λͺ¨λΈμ˜ λ¬Έμžμ—΄ ν•„λ“œ μ˜΅μ…˜μœΌλ‘œ blank와 null을 μ–΄λ–»κ²Œ 지정해야 ν•˜λŠ”μ§€ 잘 μ„€λͺ…λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
원문을 κ°„λ‹¨ν•˜κ²Œ μš”μ•½ν•˜λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:
β€’
blank: Validationκ³Ό κ΄€λ ¨ μžˆμŠ΅λ‹ˆλ‹€. Form(λ˜λŠ” Serializer)에 값을 ν•„μˆ˜λ‘œ μž…λ ₯ν•΄μ•Ό ν•˜λŠ”μ§€ μ•„λ‹Œμ§€
β€’
null: λ°μ΄ν„°λ² μ΄μŠ€μ™€ κ΄€λ ¨ μžˆμŠ΅λ‹ˆλ‹€. λ°μ΄ν„°λ² μ΄μŠ€μ˜ column에 null 값을 ν—ˆμš©ν•  것인지 μ•„λ‹Œμ§€
λ¬Έμžμ—΄ 기반의 ν•„λ“œ(CharField와 TextField λ“±)에 null=True μ˜΅μ…˜μ„ μ£Όμ—ˆμ„ λ•Œ, ν•΄λ‹Ή ν•„λ“œμ˜ 데이터가 μ—†λŠ” 상황을 두 가지(빈 λ¬Έμžμ—΄ λ˜λŠ” null)둜 해석할 수 있기 λ•Œλ¬Έμ— null=True μ‚¬μš©μ„ μ§€μ–‘ν•˜λΌκ³  ν•©λ‹ˆλ‹€.
CharField에 데이터가 μ—†λŠ” μƒνƒœλ₯Ό 빈 λ¬Έμžμ—΄('')둜 λ‚˜νƒ€λ‚΄λŠ” 것이 Django Conventionμž…λ‹ˆλ‹€.
Avoid using null on string-based fields such as CharField and TextField. If a string-based field has null=True, that means it has two possible values for β€œno data”: NULL, and the empty string. In most cases, it’s redundant to have two possible values for β€œno data;” the Django convention is to use the empty string, not NULL. β€” Django docs
κ·Έλ ‡λ‹€λ©΄ λ¬Έμžμ—΄ 기반 ν•„λ“œμ— λŒ€ν•΄ μ ˆλŒ€λ‘œ null=Trueλ₯Ό μ‚¬μš©ν•΄μ„œλŠ” μ•ˆ λ˜λŠ” 것 μΌκΉŒμš”?

Deep Dive

νœ΄λŒ€ν° 번호λ₯Ό μœ μ € ν”„λ‘œν•„μ— μΆ”κ°€ν•œλ‹€κ³  ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.
λ‚΄λΆ€ 정책에 μ˜ν•΄ νœ΄λŒ€ν° 번호 μž…λ ₯이 ν•„μˆ˜λŠ” μ•„λ‹ˆμ§€λ§Œ, νœ΄λŒ€ν° λ²ˆν˜ΈλŠ” λ°˜λ“œμ‹œ unique ν•˜λ‹€κ³  κ°€μ •ν•©μ‹œλ‹€.
ν•„μˆ˜ μž…λ ₯이 μ•„λ‹ˆλΌλŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€! ν•΄λ‹Ή 값이 ν•„μˆ˜λΌλ©΄ blank=False둜 μ§€μ •ν•˜λ©΄ κ·Έλ§Œμž…λ‹ˆλ‹€.
νœ΄λŒ€ν° λ²ˆν˜ΈλŠ” CharField둜 μ €μž₯ν•  것이기 λ•Œλ¬Έμ— null=True λŒ€μ‹  blank=True만 μ μš©ν•©μ‹œλ‹€:
class UserProfile(models.Model): ... mobile = models.CharField(max_length=11, unique=True, blank=True)
Python
볡사
μœ„μ˜ μ½”λ“œλ‘œ migration을 μ μš©ν•˜λ €κ³  ν•˜λ©΄, unique constraint violationsκ°€ λ°œμƒν•©λ‹ˆλ‹€.
μ‰½κ²Œ 말해unique=True μ˜΅μ…˜μ΄ μΆ©λŒν•œλ‹€λŠ” λœ»μž…λ‹ˆλ‹€.
원인을 뢄석 ν•΄λ΄…μ‹œλ‹€.
mobile ν•„λ“œλŠ” blank=True이고 null=False μž…λ‹ˆλ‹€.
λ”°λΌμ„œ μž…λ ₯이 μ—†μœΌλ©΄ DjangoλŠ” ν•΄λ‹Ή ν•„λ“œμ˜ 값을 빈 λ¬Έμžμ—΄("")둜 μ·¨κΈ‰ν•©λ‹ˆλ‹€.
λ¬Έμ œλŠ” unique=True μ˜΅μ…˜μœΌλ‘œ 인해, λ‹€μˆ˜μ˜ 빈 λ¬Έμžμ—΄('')을 κ°–λŠ” 행이 μ‘΄μž¬ν•  수 μ—†μŠ΅λ‹ˆλ‹€.
μœ„μ˜ ν•„λ“œμ˜ μž…λ ₯이 ν•„μˆ˜κ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— unique=True와 μΆ©λŒν•˜μ§€ μ•ŠλŠ” 빈 값이 ν—ˆμš© λ˜μ–΄μ•Όν•©λ‹ˆλ‹€.
λ”°λΌμ„œ μœ„μ™€ 같은 상황(blank=True & unique=True)μ—μ„œλŠ” null=Trueκ°€ λ°˜λ“œμ‹œ ν•„μš”ν•©λ‹ˆλ‹€.
class UserProfile(models.Model): ... mobile = models.CharField(max_length=15, unique=True, blank=True, null=True)
Python
볡사
λ‹€μˆ˜μ˜ null 값은 unique constraint violations에 걸리지 μ•ŠμŠ΅λ‹ˆλ‹€.
λ‹€μˆ˜μ˜ null이 ν—ˆμš©λ˜λŠ” μ΄μœ λŠ” null은 νŠΉμ •ν•œ 값이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
A null should not be confused with a value of 0. A null value indicates a lack of a value, which is not the same thing as a value of zero. β€” Wikipedia(Null)

Conclusion

μ •λ¦¬ν•˜λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:
β€’
λ¬Έμžμ—΄ 기반 ν•„λ“œμ—λŠ” 빈 값을 λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ null=True λŒ€μ‹  blank=Trueλ₯Ό μ‚¬μš©ν•˜μž.
β€’
λ‹€λ§Œ unique=True인 κ²½μš°μ— 빈 값을 ν—ˆμš©ν•΄μ•Ό ν•œλ‹€λ©΄ null=Trueκ°€ λ°˜λ“œμ‹œ ν•„μš”ν•˜λ‹€.