TIL on_delete=models.SET_NULL
2023.05.09 화
문제
user app에서 생성한 회원이 article app에서 게시글을 작성합니다, 이 때 회원이 탈퇴를 진행하여 db에서 삭제되었을 때, 게시글을 남기려면 어떻게해야할까요
시도
1. 검색 중 on_delete를 SET_NULL로 지정해주는 방법을 찾았습니다.
article/models.py
class Article(models.Model):
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
title = models.CharField(max_length=30)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.title)
->회원이 삭제되어도 db에 게시글은 남아있습니다 단, 게시글을 불러오려고 하면 시리얼라이저부분에서 만든 email 값이 없어 에러가 발생합니다.
1-1.시리얼라이저 부분에서 email을 받아오는 부분을 수정해봅시다.
article/serializers.py
class ArticleListSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField()
likes_count = serializers.SerializerMethodField() #<- 이 ()에 (method_name=likes) 라고 명시 할 수 도있다.
comment_count = serializers.SerializerMethodField()
#user 필드는 외래키를 이용하여 user app에서 참조한 필드
def get_user(self, obj):
if obj.user:
return obj.user.email
else:
return "탈퇴한회원"
def get_likes_count(self, obj):
return obj.likes.count()
def get_comment_count(self, obj):
return obj.comment_set.count()
def get_user() 부분을 수정합니다 가져올 수 있다면 email을 그렇지 못할 경우 "탈퇴한회원"이라 출력되게 수정합니다.
->어느정도 해결이 되었습니다, 단 삭제권한은 작성자에게 있기에 admin 페이지를 사용해야 만 삭제할 수 있습니다.
해결
user 부분을 맡으신 팀원분이 새로운 해결책을 제시해 주었습니다.
회원이 탈퇴할 경우 is_active를 False로 변경시키는 것입니다.
user/views.py
def delete(self, request):
user = request.user
user.is_active = False
user.save()
return Response({"message": "삭제완료"}, status=status.HTTP_204_NO_CONTENT)
회원이 delete를 할 시 is_active가 False로 변경되고 저장되게 만들었습니다.
삭제 시 db를 봅시다.

test08 회원이 탈퇴를 진행하여 is_active가 0으로 변경되었습니다.
이때 08회원이 작성한 게시글은 남아있지만, test08로는 로그인 및 게시글 작성이 불가능 합니다.
느낀점
궁금했습니다, 왜 삭제 기능 사용 시 회원정보를 남겨놓는지, 팀원분이 말씀하시길
실제로 기업이나 사이트에서 회원정보를 일정기간 보관해 놓는다고 합니다, 사적으로 사용되는 것이 아닌 어떤 사유에서 필요한 상황이 발생하거나 이용될 수 있기에 의무적으로 남겨놓는다고 합니다, 그럴 때 db에서 아예 회원의 정보를 삭제하지 않고 비활성화 시켜 계정을 보관한다고 합니다.
물론 on_delete=models.SET_NULL이 필요없는 건 아닐 겁니다. CASECADE하면 안되는 상황도 있기에(null값을 허용하고, 연쇄삭제가 되면 안되는 상황) 오늘도 또 배웠습니다.