2011-06-29 39 views
9

Tôi làm cách nào để sử dụng trình quản lý tùy chỉnh cho lớp học auth_user trong django?Ghi đè UserManager trong django

Trong dự án django của tôi, tôi đang sử dụng auth_user và tôi có một lớp hồ sơ cơ bản. Trong mỗi trang của trang web của tôi, tôi sử dụng một số dữ liệu người dùng và hồ sơ, vì vậy mọi truy vấn của người dùng nên tham gia hồ sơ.

Tôi muốn sử dụng select_related trong phương pháp get_query_set() trong trình quản lý tùy chỉnh, nhưng tôi không thể tìm thấy bất kỳ cách thích hợp nào để xác định hoặc ghi đè UserManager hiện có. Bất kỳ ý tưởng?

Lưu ý: Tôi không muốn ghi đè mô hình người dùng. Hoặc, để chính xác hơn, tôi đã overrode nó trong các mô hình proxy khác nhau. Tôi muốn người quản lý tùy chỉnh này được sử dụng trong mọi mô hình proxy.

Trả lời

6

Ok, cuối cùng đã tìm thấy câu trả lời đúng. Cách sạch nhất là sử dụng chương trình phụ trợ xác thực tùy chỉnh.

# in settings: 
AUTHENTICATION_BACKENDS = ('accounts.backends.AuthenticationBackend',) 


# in accounts/backends.py: 
from django.contrib.auth.backends import ModelBackend 
from django.contrib.auth.models import User 


class AuthenticationBackend(ModelBackend): 
    def get_user(self, user_id): 
     try: 
      # This is where the magic happens 
      return User.objects. \ 
       select_related('profile'). \ 
       get(pk=user_id) 
     except User.DoesNotExist: 
      return None 
3

Điều này khá xấu xí nhưng có thể bạn đã nhập vào tài sản Người dùng objects, ví dụ: trong một middleware:

# manager.py 
from django.contrib.auth.models import UserManager 

class MyUserManager(UserManager): 
    def get_query_set(self): 
     qs = super(MyUserManager, self).get_query_set() 
     return qs.select_related('profile') 

# middleware.py 
from django.contrib.auth.middleware import AuthenticationMiddleware 
from managers import MyUserManager 

class MyAuthMiddleware(AuthenticationMiddleware): 
    def process_request(self, request): 
     super(AuthenticationMiddleware, self).process_request(request) 
     User.objects = MyUserManager() 
     return None 

Sau đó, thay thế dòng trong settings.py:

MIDDLEWARE_CLASSES = (
    # ... 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    # ... 
) 

bởi:

# settings.py 
MIDDLEWARE_CLASSES = (
    # ... 
    'yourapp.middleware.MyAuthMiddleware', 
    # ... 
) 

Note1: Mã này được hoàn toàn theoric, không bao giờ thử nghiệm tôi cũng không có thời gian.

Lưu ý2: Tôi không thể khuyên bạn nên sử dụng giải pháp này từ quan điểm bảo trì dài hạn.

Lưu ý3: Nếu ai đó đề xuất điều gì đó khác, bạn có lẽ nên lắng nghe họ nhiều hơn tôi.

Lưu ý4: Là một ý tưởng tốt hơn, tại sao không cố truy vấn Tiểu sử, đây là lớp mô hình bạn có toàn quyền kiểm soát? Tuy nhiên, bạn luôn có thể truy xuất đối tượng người dùng từ tiểu sử, vì vậy…

+0

Vì tôi không thể tìm thấy bất kỳ cách nào rõ ràng hơn, tôi sẽ chấp nhận câu trả lời này. Tuy nhiên, tôi đã điền một báo cáo lỗi trong django BT. Chờ và xem. https://code.djangoproject.com/ticket/16379 –

+3

Bạn thực sự không nên chấp nhận câu trả lời này, bởi vì người mới bắt đầu có thể kết luận rằng đó là một cách tiếp cận có thể chấp nhận để giải quyết vấn đề bạn nêu ra, trong khi nó không phải. – NiKo

+0

Đã cố gắng và nó không hoạt động ... Sẽ là một giải pháp đơn giản đối với tôi – James

Các vấn đề liên quan