django signal에 대해 간단하게 알아봅시다.

웹/장고 2022. 12. 10. 05:00

 django에서 블로그를 생성할 때 기본 포스트가 생성되게 하고 싶습니다. 혹은, 아이디를 만들 때 포스트가 새로 만들어지게 하고 싶습니다. 이럴 때 어떻게 하면 좋을까요? view 단에서 user가 만들어지면 처리하게 할 수도 있겠습니다만, signal 등으로 처리하는 것도 나쁘지 않은 선택입니다. 다만, 공식 문서에서는 warning에 이해하기 힘든 로직이 작성될 수 있다고 하는데요. 레코드가 추가되는 부분하고, 그럴 때 발생하는 signal을 처리하는 부분이 분리가 되어 있다 보니 그러지 않나 싶습니다. 사실 linux에서 sigaction을 써 보셨다면 공감하실 수도 있을 듯 합니다.

 

 그럼에도 불구하고, 저는 생각보다 유용하게 써먹었습니다. 그래서, 이번 시간에는 signal을 알아보도록 하겠습니다. 조금 더 자세한 내용은 문서를 보면 되겠습니다.

 


 프로젝트 구조는 이러합니다. app 패키지 밑에 있는 것들만 건드리겠습니다.

 

 먼저, apps.py에 있는 AppConfig를 봅시다. 여기에서 ready 메소드를 override 합시다. ready 메소드에는 app.signal을 import 하겠습니다. 

 

 다음에, signal.py에는 요렇게 작성해 주겠습니다. 여기서 signal 이름은 post_save입니다. 그리고 sender는 User입니다. 시그널을 보내는 주체 정도라고 생각하시면 되겠습니다.

 

 

 유저의 staff status를 바꿔 보겠습니다.

 

 

 그러면, user_created 함수가 생성됨을 알 수 있는데요. created 필드가 False인 것을 확인할 수 있어요. 이는 유저가 create 되는 것이 아니라, 수정된 것이기 때문입니다. 이제, post_save를 이야기 해 봅시다. post_save는 save() 메소드가 호출된 직후에 일어납니다. 이를 도식화 시키면 아래와 같습니다.

 

 반면에 pre_save는 save()가 호출되기 전에 일어납니다. 고로, 이런 흐름이라는 것을 알 수 있어요.

 

 

 우리는 유저가 생성된 후에 post가 생성되면 되니, signal을 post_save를 걸어버리면 됩니다.

 

 

 코드를 봅시다. created flag가 참이라면, Post를 생성합니다. instance는 생성된 유저를 의미합니다. 보면, 새로 생성된 유저 이름을 환영한다는 문구를 붙여서 post를 작성함을 알 수 있습니다. 결국 특정 이벤트가 트리거 되었을 때 handler를 작성해서 처리한다는 것을 알 수 있어요. sigaction 같은 것들이 생각나는 부분입니다.

 


 이제 유저를 생성해 보겠습니다.

 

 post 테이블을 보니 Hello chokw3이라는 내용이 들어간 글이 생성되었습니다. 여담으로 설정값 중에 dispatch_uid라는 값이 있는데요. 이것은  부분을 잘 읽어보시면 도움이 되실 듯 합니다.