장고(Django) request.user를 입맛대로 바꾸기 :: 2010/03/30 13:20

이전 포스트 장고(Django)의 사용자이름 표기(get_full_name)에도 소개했듯이 사용자(User)를 어플리케이션 입맛에 맞도록 바꾸는 일은 종종 필요하다. MyUserProfile 같은 모델을 사용하여 프로파일 정보를 외부키로 연결하여 관리하기도 하고, 모델상속을 이용하여 확장할 수도 있다.

이전 포스트에서는 get_full_name 를 오버라이드 하기위해 모델상속을 이용했다.
import re
from django.contrib.auth.models import User

class MyUser(User):
    class Meta:
        proxy = True
    def get_full_name(self):
        is_english = re.match(r'^\w', self.first_name)
        if not is_english:
            return "%s%s" % (self.last_name, self.first_name)
        return super(MyUser, self).get_full_name()
MyUser를 정의한 이후로 모델에서 사용하는 User는 모두 MyUser를 가리키게 함으로써 get_full_name 을 내 입맛에 맞게 바꾸긴 했지만 내맘대로 안되는 곳이 있으니, request.user는 여전히 User를 사용한다. RequestContext 를 써서 전달되는 user 컨텍스트는 나의 조작을 거치지 않고 그대로 템플릿으로 흘러들어가서 원래 자기의 get_full_name를 내뱉는다.

구글링해본 결과 이럴때는 authentication backend 를 재정의해주면 된다. (Extending the Django User model inheritance 참고)

즉, 어플리케이션 디렉토리에 auth_backends.py 파일을 만들고,
from django.contrib.auth.backends import ModelBackend
from django.core.exceptions import ImproperlyConfigured
from myapp.models import MyUser

class MyUserModelBackend(ModelBackend):
    def authenticate(self, username=None, password=None):
        try:
            user = MyUser.objects.get(username=username)
            if user.check_password(password):
                return user
        except MyUser.DoesNotExist:
            return None
    def get_user(self, user_id):
        return MyUser.objects.get(id=user_id)
라고 정의한 뒤, settings.py 에서 다음을 추가한다.
AUTHENTICATION_BACKENDS = (
    'myapp.auth_backends.KpaaUserModelBackend',
)
그러면 이후부터 request.user 는 MyUser 가 된다.

이상은, 사용자를 확장하여 쓰고자 할때 유용한 팁이긴 하지만, 어플리케이션을 조합하여 사용하기를 권장하는 장고의 방침을 생각할 때 그리 권장할만하지 않다. 가능한 안쓰면서 필요한 경우에만 적용하기.
Trackback Address :: http://yong27.biohackers.net/trackback/365
Name
Password
Homepage
Secret