2012-01-12 36 views
1

我有Django的User模型元類,我用它來添加額外的方法(過於簡化版本):使用代理類,而不是用戶的request.user

# project.models.pie_lover.py 

from django.contrib.auth.models import User 

class PieLover(User): 
    class Meta: 
     app_label = "core" 
     proxy = True 

    def likes_pie(self): 
     return True 

在我看來,我想得到登錄PieLover,看看他是否喜歡餡餅(因爲PieLover總是喜歡餡餅,所以很可笑,但在現實世界中情況可能並非如此)。我的問題在於Django登錄用戶的方式,我使用內置的login(request)函數,因此存儲在request.user中的對象是User對象,而不是PieLover

# project.views.like_pie.py 

from ..models.pie_lover import PieLover 

def index(request): 
    pie_lover = request.user 

    if pie_lover.likes_pie(): 
     print "Try pie, try!" 
    else: 
     print "BLASPHEMER!" 

如果我嘗試這樣做的Django告訴我,User對象有沒有方法likes_pie這是可以預料的是request.user不是PieLover實例。

作爲一種快速解決方法,我只需要獲得與User具有相同ID的PieLover,但這意味着額外的數據庫命中。

我該如何讓Django默認在請求中使用PieLover? 我在想,不是讓另一個數據庫查詢得到正確的PieLover對象來創建一個新的PieLover對象,並在初始化時將request.user傳遞給它,但我不知道這是什麼意思。

回答

6

打探後,我發現,是什麼在我看來,要訪問一個給定User實例PieLover方法最簡單和非hackish的方式。我已經將此添加到自定義中間件:

from models.pie_lover import PieLover 

class PieLoverMiddleware(object): 
    def process_request(self, request): 
     request.pie_lover = PieLover(request.user) 
+0

研究OSQA的擴展用戶中間件。 – osa 2014-06-16 10:17:34

1

我該如何讓Django在請求中默認使用PieLover?

你不知道。

閱讀本你做任何事情之前:https://docs.djangoproject.com/en/1.3/topics/auth/#storing-additional-information-about-users

您的「分機」用戶應該是所有的在單獨的模型的擴展方法一個單獨的模型。

然後,您可以使用已提供的get_profile()方法,從用戶(請求中)輕鬆導航至您的擴展。

+0

S.Lott OP並沒有談論向模型中添加額外字段,只是幾種方法。我認爲最好的方法是單獨處理lik @Ronnie或使用自定義的AuthenticationMiddleware – armonge 2012-01-12 23:10:51

+0

@armonge:「並不是在向他的模型中添加額外的字段」。你確定?我的經驗是,用戶類的所有這些「增加」都涉及數據。這可能是罕見的例外。我仍然會建議內置的受支持的擴展機制總是最好的。 – 2012-01-12 23:13:19

+0

@ S.Lott:不需要,只需要添加一些方法,我沒有額外的數據。即使是這樣的情況,當我可以輕鬆寫入request.user.pie_lover.some_new_method() – yoshi 2012-01-13 00:04:55

0
from django.contrib.auth import models as auth_models 

def _my_func(self): 
    return True 

auth_models.User.my_func = _my_func 
相關問題