본문 바로가기

개인 스터디/오류

[Django] on_delete=models.SET_NULL에서 주의할 점

django 실습 도중 landing.html에서 문제점을 발견했다.

원래 내가 하려던 기능은 post의 author를 불러오고, 함수를 만들어 author가 상속받은 user의 email에 따라 달라지는 아바타 이미지도 함께 가져와 landing.html에 불러오려 했다.

이렇게 보이도록!

 

#blog/models.py

class Post(models.Model):
	# 생략
    author=models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    
    def get_avatar_url(self):
        if self.author.socialaccount_set.exists():
            return self.author.socialaccount_set.first().get_avatar_url()
        else:
            return f'https://doitdjango.com/avatar/id/1461/f136db71fc1aec42/svg/{self.author.email}'

 

on_delete 설정은 참조한 모델이 사라져도 None으로 설정되고 참조한 데이터는 사라지지 않는 models.SET_NULL과 참조한 데이터가 사라지면 함께 사라지는 models.CASCADE가 있다.

여기서 문제점은 SET_NULL설정 때문에 생겼다.

유저가 삭제 됐을 때, post데이터는 사라지지 않지만 참고할 user의 email이 없어 get_avatar_url 함수가 작동하지 못하고 에러를 일으켰다.

post_detail.html의 댓글 같은 경우에는 같은 함수를 사용했지만 models.CASCADE로 설정하여 문제가 없고, post_list.html에서는 함수를 이용하지 않고 유저가 사라지면 None으로 자동으로 author가 바뀌어 문제가 없었다.

 

 

 

 


# single_pages/landing.html

{% if post.author %}
<img class="mr-1 rounded-circle" width="20px" src="{{ post.get_avatar_url }}" alt="{{ post.author }}">
{{ post.author.username }}
{% else %}
None
{% endif %}

해결은 간단하게 했다...

post.author가 존재하는 경우에만 함수를 불러오고, 존재하지 않으면 None으로 표시하였다.

 

성공!

간단하지만...model.SET_NULL을 처음 사용하면서 오류가 났을 때 조금 헤매서 정리했다.