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

django - Error HINT: Add or change a related_name argument to the definition for 'instagram.Post.author' or 'blog1.Post.author'.

by 다니엘의 개발 이야기 2022. 12. 14.
320x100

models.py의 간단한 부분을 고쳐주고 

makemigrations, migrate를 하려고하니깐 에러가 떴다.

 

ERRORS:
blog1.Post.author: (fields.E304) Reverse accessor 'User.post_set' for 'blog1.Post.author' clashes with reverse accessor for 'instagram.Post.author'.
        HINT: Add or change a related_name argument to the definition for 'blog1.Post.author' or 'instagram.Post.author'.
instagram.Post.author: (fields.E304) Reverse accessor 'User.post_set' for 'instagram.Post.author' clashes with reverse accessor for 'blog1.Post.author'.
        HINT: Add or change a related_name argument to the definition for 'instagram.Post.author' or 'blog1.Post.author'.

#1 찬찬히 에러메세지 보기

 

둘째줄에 나오는 첫번째 힌트에 보면 add(추가)하거나 change(변경)하라고 나온다.

related_name argument to definition - 쉽게 말하자면 "정의된" 관계되어있는 이름

for - 그것을 위해서

'blog1.Post.author' or 'instagram.Post.author'

blog1~~를 쓸건지 instagram~~~을 쓸건지 결정해라


#2 힌트대로하기

 

이제 힌트대로 확인을 해보자면

blog1이라는 앱에도 Post가 있고

instagram이라는 앱에도 Post라는 클래스가 있어서 충돌을 하는거니깐

무언가를 다르게 추가해주거나 변경해달라고 한다.

 

기존에는 blog1 앱이든 instagram 앱이든 Post클래스의 author를

author = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

라고 정의해주었다.

 

이걸 해결하는 간단한 방법은 null = True

라고 해주면 사실 해결은 된다. 하지만 추후에 데이터를 관리하는데 어떤거였는지는 까먹었지만

문제가 있을거라고 말씀하시는걸 듣긴 했다.

따라서 null=True가 아닌 다른 방법을 하려고 한다.

 

하지만

 

blog1앱의 models에서 Post 클래스 중 author를

author = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='+')

라고 해줌으로써 related_name에 +라는 문자값을 부여해주었다.

 

그리고

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:

라는 메세지가 뜨게 된다.


#3 메세지에 대한 해석

 

it is impossible - 그것은 불가능하다

to add - 추가할

non-nullable field 'author' - 비어있는 상태가 될수없는 author라는 필드는

to post without specifying - 개제하지 못한다. 명확한 나열없이

This is because the database needs something to populate existing rows. - 왜냐하면 데이터베이스는 무언가 머물러 있을수있는 존재하는 행이 필요하다

Please select a fix - 그러니 고치는 것을 골라줘라

 

쉽게 옵션1은 "지금 그 값을 입력하겠다"

옵션2는 명령수행을 중단하겠다.

 

즉, 메세지의 힌트를 읽고나서는 데이터베이스에 대해서 이슈가 있기에 이것을 고쳐줘야한다는 것을 알수있다.

그러나 근본적으로 데이터베이스의 구조라든지 장고가 구현되는 원리를 알지 못하면 해당 문제는 풀수없다에 가까운것같다 ㅠㅠ


#4 터미널 메세지에 옵션1로 진행

 

일단 기본 전제로는 이미 "지금 그 값을 입력하겠다. 라고 해서 중요값은 전달 된 거라고 보면 된다.

 

그리고 #3에서 말했던 옵션1 즉, "지금 그 값을 입력하겠다"로 진행해보겠다.

그러면 또다시 안내 메세지와 함께 shell을 킨듯한 >>>가 나오게 된다.

Please enter the default value as valid Python.
The datetime and django.utils.timezone modules are available, so it is possible to provide e.g. timezone.now as a value.
Type 'exit' to exit this prompt

 

첫째줄 - 유효한 파이썬 결과값을 입력해줘

둘째줄+셋째줄 - 시간모듈등에 대해서는 사용할 수 있어. 내가 예를들어 줄게 timezone.now의 value 타입이 exit면 prompt에 exit라고 입력해줘

 

즉, 전체적으로 통틀어서 보자면 #2에서 문제가 되었던 2개의 충돌되는 클래스의 필드값중 변경한 필드값에 대해서

변경된 필드값의 타입에 맞추어서 프롬프트(>>>에다 입력하는거)에 입력하는 것이다.


#5 프롬프트(prompt)에 1입력

 

프롬프트에 1을 입력해보자.

그러면 해당 앱의 author에 대한 pk값(id값)에 대해서는 모두 1로 변경된다.

그리고 적용된다.

 

이런 변경이 싫다면 이미 makemigrations를 실행해버린 경우, 생성된 migrate파일을 삭제하고 설정값을 재조정 후에 다시 makemigrations를 하거나

 

아니면 이미 모두 1로 바뀌어버린 값에 대해서 SQL명령 등으로 1부터 순차적으로 숫자를 변경해주는 방식을 사용해도 되겠다.

300x250