본문 바로가기
개발일지/Django

Django - It is impossible to add a non-nullable field (해결 및 설명)

by 개발에정착하고싶다 2023. 1. 2.

#0 개요

 

상황이야 여러가지가 있을 수 있겠지만, 보통의 경우에는

models.py에 model을 하나라도 등록해두고 사용하던 중에, model 내부의 속성을 한개라도 더 추가한다면

발생하게 되는 에러에 대해서 알아보고자 한다.

 

#1 실제 상황 및 정리

 

내가

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=30)
    hook_text = models.CharField(max_length=100, blank=True)
    content = models.TextField()

    head_image = models.ImageField(
        upload_to='blog/images/%Y/%m/%d/', blank=True)
    file_upload = models.FileField(
        upload_to='blog/files/%Y/%m/%d/', blank=True)
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

 

이렇게 모델을 정의하고

저 Post라는 모델안에 데이터를 1개 이상 넣게 되었을 때 관리자 화면으로 보자면

이런 모습일 수 있다.

그리고 한개 이상의 데이터 레코드(한 id(pk)에 부여된 데이터 셋이라고 이해하면 됨)에

데이터를 이미 넣은 상태에서

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=30)    
    hook_text = models.CharField(max_length=100, blank=True)
    content = models.TextField()
    
    head_image = models.ImageField(
        upload_to='blog/images/%Y/%m/%d/', blank=True)
    file_upload = models.FileField(
        upload_to='blog/files/%Y/%m/%d/', blank=True)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

	# 새롭게 추가	
    author = models.ForeignKey(User, on_delete=models.CASCADE)

이렇게 author라는 속성을 추가할 경우 (1개 이상의 추가 속성을 추가할경우)

 

#2 에러문구 해석

 

터미널에 python manage.py makemigrations를 하게되면

It is impossible to add a non-nullable field 'author' to post without 
specifying a default. This is because the database needs something 
to populate existing rows.
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with 
 a null value for this column)
 2) Quit and manually define a default value in models.py.
Select an option:

이런 안내 문구가 뜬다.

찬찬히 번역을 해보자면

 

@ 기본 번역

이 author라는 필드는 post(지금 다루고 있는 models에 정의된 class)에 비어있지 않은 값이라,

자세한 결과 없이는 추가 할 수 없다.

무언가라도 데이터 레이블에 있어야 하기 때문이다.

고치는 방법을 골라봐라

 

@ 배경 설명

-> (쉽게 설명을 곁들여서 바꾸면) 필드(각 데이터의 셀이라고 생각하면 된다. 엑셀시트의)에는 null이라면 비어있어도 되지만 not-null이라면 null값을 허용하지 않는다 = 즉, 비어있으면 안된다.

하지만 author라는 추가 속성의 정의에는 null=True라고 해서 공백을 허용해준게 아님에도 속성을 추가하게 되면 자연스럽게 공백이 생기므로

 

1) 기존속성들

title = xx

hook_text = bla

content = bla

(그외 문자나 숫자가 아닌 것은 생략)

 

2) 만약 author라는 속성을 기존속성들에 추가하게 되면

#1에서 보면 3개의 레이블값들이 있는데 여기에 각각

title = xx

hook_text = bla

content = bla

(그외 문자나 숫자가 아닌 것은 생략)

author = 공백

이 되는 것이다.

(미안하지만 이게 이해가 안된다면 models를 좀 더 경험해보고 오는게 좋을듯 싶다. 이것만해도 문외한에게 설명하려면 상당히 길어질 것 같다)

 

@ 배경 이후의 쉬운 설명

그렇기때문에 author를 니가 추가했는데, 거기에 null=True가 아니였다.

다른 레이블 값에도 null값에 대해서 불문명한 author를 추가할수는 없으니

이를 해결할 수 있는 2가지 방법중에 골라봐라

 

@ 각 문항에 대한 해석

1. 일회성 방법을 쓸래?(그러면 니가 선택하게 되는 레이블 중 하나의 컬럼(id혹은pk값)을 골라봐

그걸 기준으로 모든 레이블에 똑같은 값을 적용해줄게 (지금 이 전체 포스팅 하에서는 class Post에 들어가는 author속성에 한에서 말하는 중)

 

2. 여기서 멈추고 너가 다시한번 models.py에서 (null에 대해 명확히하고) 돌아올래?


#3 결론

 

말을 쓰면서도 이게 배경지식이 기초적인 수준이라도 깔려있지 않다면 이해가 안될것같다;

또 기초가 충분한데 저것만 알기를 원하는 사람이 보기에는 지나치게 복잡한것같고;

암튼 내가 쓴 글이 필요할 사람도 있을테니깐 내비둬야겠다.

 

결론적으로 2를 선택하게 되면 null에 대해서 새로 추가된 속성에 null값을 허용할건지 말건지 결정해야한다.

null=True를 할경우 빈 값으로 둬서 상관없는데, null이 채워져야하면 어떻게든 채워넣을 방법을 찾아야한다.

 

1번으로써 내가 선택한 id에 해당하는 레이블의 임의 author데이터를 모든 레이블에 적용한다는 것이

실무에서도 사실 쓰기에 무리가 없는 방법이라고 생각하는데,

 

1)

우선은 1번을 눌러서, 어떤 id값을 선택할건지 정할때 마찬가지로 1 하고 엔터를 누르게 되면

모든 레이블의 author 값은 id 1과 같은 값을 가지게 된다.

 

2)

그리고 나서는 필터를 이용하든, if문같은것을 곁들인 반복문을 이용하든, 본인에게 확실한 방법으로

맞는 데이터들을 채워주게 되면 그것으로 충분할 것 같다.