IT Study

M2M필드 적용시, Django Admin에서 주의할 점

masoume 2016. 3. 31. 08:12
untitled

새 글을 추가하거나 댓글, 태그 등을 추가할 때, 웹 페이지보다 admin을 선호하는 편이다.(사실은 template하고 view 구현을 제대로 못한 상태에서 모델에 객체 추가하느라 admin을 애용합니다.....) 오늘도 어김없이 admin을 통해 새 글을 작성했는데 이해할 수 없는 결과가 나와 이리저리 원인을 찾아 헤맸다.

일단, 내가 하고자 했던 건,


  1. 새 글(post)을 작성한다.
  2. 새 글이 작성되면 post_save 시그널로 메소드가 실행된다.
    1 ) 글 내용에서 해시태그들만 뽑아온다.
    2 ) 뽑아 온 해시태그들은 Tag 모델로 저장한다.
    3 ) Post와 Tag는 many to many 관계이므로, manyrelated_manager를 이용해 태그를 포스트에 등록한다.


하지만, 2-2까지는 잘 되더니 정작 목표했던 2-3이 되질 않았다. 메소드를 다시 짜보고, 모델을 잘못 만들었나 싶어 migrate도 해보다가 print와 ipython을 이용하여 메소드 중간중간 값들을 확인해봤다. 그리고 확인한 사실은 메소드엔 문제가 없었다는 것... 문제는 시그널 메소드가 끝난 후에 있었다.

admin을 통해 객체를 생성할 경우 ModelAdmin.save_model()가 실행되고 ModelAdmin.save_related()가 실행된다. 새로 만든 객체가 저장된 후(여기선 post), 그 객체와 관련된 모델들(여기선 tag들)의 값이 저장된다. 위 경우로 설명하자면,


  1. 새 글(post)을 작성한다.
  2. ModelAdmin.save_model() 실행 -> post 객체가 저장됨
  3. post_save 시그널로 메소드가 실행된다.
    1 ) 글 내용에서 해시태그들만 뽑아온다.
    2 ) 뽑아 온 해시태그들은 Tag 모델로 저장한다.
    3 ) Post와 Tag는 many to many 관계이므로, manyrelated_manager를 이용해 태그를 포스트에 등록한다. e.g) post.tag_set.add(new_tag)
  4. ModelAdmin.save_related() 실행
    1 ) 해당 post와 Tag모델의 M2M 관계는 깨끗이 지워진다 (cleaned_data란 메소드가 있네효? ^-T)
    2 ) admin from에서 작성된 값으로 관계가 다시 설정된다.


망할 4번이 원인이었다. ㅋㅋㅋ 아무리 포스트에 태그를 add해도 4번처럼 깨끗이 청소되고 말았던 것. 게다가 admin form에서도 태그값을 따로 정해주지 않아서 4-2에서 다시 설정할 값도 없었던 것이다. 그래서 자꾸 관련 태그 없다고 나오고..... 난 분명 입력해줬는데 얘 왜 이러니.. 울고 싶고.. 막 집에 있어도 집에 가고 싶고.. 디버깅 툴 있었으면 좋겠다 생각하고... 아무튼, admin이 아닌 웹 페이지에서 글을 생성하면 tag는 잘 들어간다. template과 view를 미리미리 잘 만들어놔야겠다 ^^



admin에서 이 문제를 해결하고 싶다면 ModelAdmin.save_related 메소드를 override하면 된다. 코드는 잘 정리해준 서역남이 있어서 여길 참고