티스토리 뷰

프로젝트를 진행하면서 모델을 설계했는데 일대일 관계에 있는 모델을 생성해야했다. 처음 설계 시에는 별다른 생각없이 그냥 설계를 했는데, API를 테스트하면서 부모 모델이 생성되면 자식 모델도 default로 같이 생성되는 형태의 로직이 필요했다 -> 아니 필수적이였다.

 

예를 들어 User하나에는 반드시 Allergy 모델이 있어야 한다고 하자.

User 하나가 생성되면 ->  Allergy 모델도 default로 생성이 되어야한다.

일대일 대응 모델을 자동으로 생성해주는 코드는 Django docs의 signals를 보면 알 수 있다.

signal을 통해 특정 sender는 어떤한 행동이 취해졌음을 receiver에게 알릴 수 있다.

프로세스에서 signal을 전달하여 신호를 주고받는 느낌? 과 비슷한 맥락인 것 같다.

 

즉 signal을 이용하여 sender와 receiver가 신호를 주고 받는 개념을 이용하는 것이다.

User 모델과 Allergy모델을 각각 다음과 같이 정의한다.

# users.model

class User(AbstractUser):
    name = models.CharField(max_length=255)
    email = models.CharField(max_length=255, unique=True)
    password = models.CharField(max_length=255)
    gender = models.SmallIntegerField(choices=GENDER_CHOICES, null=True)
    username = None

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []


------------------------------------------------------------------------------------------
# allergy.model

class Allergy(models.Model):
    egg = models.BooleanField(default=False)        # 1. 난류
    milk = models.BooleanField(default=False)       # 2. 우유
    buckwheat = models.BooleanField(default=False)  # 3. 메밀
    peanut = models.BooleanField(default=False)     # 4. 땅콩
    bean = models.BooleanField(default=False)       # 5. 대두
    wheat = models.BooleanField(default=False)      # 6. 밀
    
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="allergy")

 

여기서 장고에서 제공하는 @receiver 라는 데코레이터를 사용하여 자동 생성을 구현할 수 있다.

@receiver(post_save, sender=User)
def create_Allergy(sender, instance, created, **kwargs):
    if created:
        Allergy.objects.create(user=instance)
        # print('allergy model created success')

@receiver의 첫 번째 인자인 post_save는 signal의 한 종류로 연결된 객체가 저장(save)되었을 때 신호를 받는다. 신호의 종류는 장고에서 제공하는 signals.py를 들어가보면 더 자세히 알 수 있다. 신호를 보내는 객체는 두 번째 인자인 sender=User로 정의할 수 있다.

 

create_Allergy 함수의 인자들을 설명해보면 post_save로 넘어온 User 객체는 instance에 남아있다.

 

- sender: signal 보내는 객체 (User)

- instance: signal을 보낸 객체에서 만들어진 object (User user1)

- created: 객체가 생성되었는지를 알려주는 boolean 값 

 

위 인자들을 이용하여 유저 객체가 생성되었을 때 해당 유저와 관련된 알러지 객체를 자동으로 생성하는 로직을 구현할 수 있다.

 

 

댓글