get_or_create는 장고에서 제공하는 메서드로 말 그대로 객체가 존재하면 get하고, 없으면 create 하는 메서드이다.
이 메서드는 실행되면 (object, created) 이라는 튜플을 반환하는데, object는 get하거나 create된 객체 자체고, created는 boolean 값으로 create된 경우 True, get한 경우 False로 반환된다.
예시를 들자면 카카오 소셜 로그인 처리해서 받은 사용자의 정보가 기존 회원 DB에 있으면 get하고 없으면 create 되는 식으로 활용할 수 있다.
만약 get_or_create를 쓰지 않는다면 if filter().exists() 등으로 분기를 만들고 objects.create() 하거나 objects.get()해줘야 하므로 코드가 길어질 수 밖에 없다. 이렇게 길어진 코드를 줄일 수 있다는게 get_or_create의 장점이다
get_or_create가 편리하긴 하지만 동시다발적으로 이 메서드가 실행될 경우에 경쟁조건(race condition)이라는 문제로 인해 단순히 objects.create()하듯이 코딩하면 안되고 defaults라는 파라미터를 활용해야 한다.
또한 unique한 속성의 필드를 활용하는 게 좋다고 한다.
#defaults 안쓰는 경우, race condition 문제 있음
user, is_created = User.objects.get_or_create(
kakao_id = kakao_account['id'],
email = kakao_account['kakao_account']['email'],
nickname = kakao_account['kakao_account']['profile']['nickname'],
thumbnail_url = kakao_account['kakao_account']['profile']['thumbnail_image_url'],
)
#defaults 사용
user, is_created = User.objects.get_or_create(
kakao_id = kakao_profile['id'],
defaults = {
'email' : kakao_profile['kakao_account']['email'],
'nickname' : kakao_profile['kakao_account']['profile']['nickname'],
'thumbnail_url' : kakao_profile['kakao_account']['profile']['thumbnail_image_url']
}
)
출처:
https://docs.djangoproject.com/en/4.0/ref/models/querysets/#get-or-create