-
Django SignalDjango 2022. 9. 29. 16:14
Django Signal?
어떤 작업이 실행되거나, 실행되기 전에 신호를 발생시켜 그때에 지정해놓은 동작을 수행할 수 있게 한다.
예시를 들어보자.
class User(models.Model): id = models.CharField() name = models.CharField() age = models.PositiveIntegerField() gender = models.CharField(choices=Gender.choices) class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) name = models.CharField() gender = models.CharField() short_info = models.TextField() profile_img = models.ImageField()이런 유저 모델과 프로필 모델이 있다고 가정해보자
name, gender 등 유저 모델이 가지고 있는 필드 값이 프로필 모델에도 똑같이 필요하다.
물론 회원가입 시 프로필 모델을 만들고 연결해줄 수도 있다.
하지만 Signal을 이용해 유저 모델이 생성되었을 때 자동으로 프로필 모델이 생성되게 구현해보자.
# apps.py class UserConfig(AppConfig): name = "users" def ready(self) -> None: """Import signals module to register.""" from . import signals# signals.py @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created == True: profile = Profile( user=instance, name=instance.name, gender=instance.gender ) profile.save()위의 예시대로 구현해볼 수 있다.
@receiver(Signal, sender) 형태이다.
기본적으로 장고가 내장하고 있는 signal
- pre_init, post_int
- pre_save, post_save
- pre_delete, post_delete
- m2m_changed
- class_prepared
- pre_migrate, post_migrate
- request_started
- request_finished
- got_request_exception
정리해보면 위의 내장 Signal의 이름처럼 상태가 변화할 때 실행되는 함수를 Signal을 적용해 구현할 수 있다.
그렇다면 Signal을 모두 적용시키는 게 권장되는 방법일까?
아주 제한적인 경우를 제외하고는 Signal 사용을 권장하지 않는다고 한다.
그 이유로는 관련된 로직임에도 코드가 분리되고 코드가 쓸데없이 길어지는 영향을 끼치기 때문이다.
제한적으로 권장하는 경우는 아래와 같다.
- 써드파티 라이브러리 동작을 확장할 때
- delete signal
- 하나의 Signal을 여러 모델에서 사용할 때
- 다른 app과의 의존성을 줄이기 위해
어떤 곳에 Signal을 적용시키려 할 때 충분히 검토하여 적용하자
떠오르는 예시로는 새 댓글이 작성될 때 작성자에게 알리는 부분 같은 곳에 활용하면 좋을듯하다.
'Django' 카테고리의 다른 글
Django Redis cache (1) 2023.01.03 Django timezone (0) 2022.10.14 Django UniqueConstraint (0) 2022.10.07 Django unittest pytest (0) 2022.09.28 Django ORM Manager, QuerySet (2) 2022.09.26