안녕하세요. 이번 시간에는 admin의 edit 메뉴에서 편집할 수 있는 필드들을 어떻게 보여주는지 알아보고 응용해 보도록 하겠습니다. 이전에 한 번 말씀을 드렸을지 모르겠지만, staff라고 해도 퍼미션에 is_superuser를 설정할 수 있는 권한이라던지, 비밀번호 등을 함부로 주면 안 될 겁니다. 이런 것을 방지하기 위해, 보여지는 필드들을 비활성화 시키는 방법이 있어요. 그 방법도 같이 알아볼게요.

 


 먼저, get_fieldsets를 오버라이드 해 보겠습니다. obj가 None이면 self.add_fieldsets를 deepcopy한 것을 리턴합니다. 그게 아니라면, self.fieldsets를 deepcopy한 것을 리턴합니다.

 

 self.add_fieldsets를 먼저 봅시다. fields가 username, password1, password2가 있습니다. admin에서 유저를  추가할 때 나오는 3개의 필드를 의미합니다.

 

 다음에, self.fieldsets가 있는데요. 유저를 수정할 때 나오는 필드들과 관련이 있음을 직관적으로 알 수 있습니다. username, password, first_name, last_name, email 등이 있네요. 이제, 우리는 2가지 경우에 대해서 get_exclude의 obj가 어떻게 변하는지를 보겠습니다. 먼저 유저를 추가하는 메뉴를 호출한 경우입니다.

 

 

 이 경우 obj는 None이 됩니다.

 

 그런데, 유저 이름이 Abcde인 유저를 수정하려고 접근한 경우, obj는 User Abcde에 대한 정보가 들어옵니다. 결국 위 코드는 obj가 None이면 유저를 추가할 때, 그게 아니라면 특정 유저를 수정하는 요청이 들어왔을 때, fieldset에 어떤 것을 보여줄지를 결정합니다.

 

 


 이제 요구사항을 봅시다. 내가 superuser가 아닐 때, is_superuser, is_staff 필드가 안 보이게 하겠습니다. 그리고 staff 이상의 계정에 대해, 자기 자신이 아니면 password도 edit 창에 안 보이게 할 겁니다. 먼저, 조건에 따라서 exclude 필드들을 list에 넣습니다.

 

 

 60번째 줄은 최고 권한을 가진 유저에 대한 처리를 하는 것입니다. 그냥 막바로 어떠한 수정도 없이 edit_fieldsets를 리턴해 버립니다. 62번째 줄은, 수정하려고 하는 유저가 최소 staff 이상인데요. 로그인 한 유저하고 다른 경우에, password도 필드에 보여주지 않아요. 63번째 줄에 exclude 패턴에 "password"를 추가하는 것을 보면 알 수 있습니다.

 

 

 이제 다시 디버그 창을 봅시다. edit_fieldsets를 순회한다고 생각해 봅시다. 그러면 2개의 원소가 있는 튜플들을 순서대로 순회하게 될 겁니다. 이 튜플들에서, 'fields'에 대한 정보에 접근하기 위해서는, [1]['fields']로 접근하면 됨을 알 수 있어요. 그림을 그려 봅시다.

 

 

 우리는 군청색 부분을 바꾸면 됨을 알 수 있어요. 여기에, 보여질 필드들에 대한 정보가 저장되기 때문입니다. tuple은 불변 클래스이지만, dictionary는 그렇지 않습니다. 따라서, 우리는 해당 딕셔너리의 "field" 키를 가진 것의 value를 다른 것으로 대치시키면 됩니다.

 

 

 65번째 줄은 대치 작업을 수행합니다. 66번째 줄이 문제인데요. 기존에 edit_field[1]["fields"]에 있었던 내용들 중, exclude에 속하지 않은 것들만 가져와서 tuple로 변환합니다. ~ not in exclude 구문을 보면 눈치 챌 수 있습니다. 65번째 줄에 tuple 구문이 있는데요. 이는, 필터링한 결과를 다시 튜플로 변환하기 위함입니다.

 

 

 이제 확인해 봅시다. staff 계정이고, 현재 로그인 된 계정은 chokw1입니다. chokw에 대해서 password를 변경하는 폼 자체가 보이지 않습니다. 그런데 폼만 안 보일 뿐이지 링크는 살아 있습니다. 이것을 막는 방법은 다음에 이야기 해 보도록 하겠습니다. 다음에, staff가 아닌 다른 계정들은 어떨까요?

 

 

 Active까지만 활성화 되고, 나머지 체크박스는 활성화가 안 된 것을 볼 수 있습니다.