2010-01-24 62 views
4

我正在嘗試學習Django,並且希望得到任何具有任何MVC/MTV/PHP/Ruby框架經驗的人的反饋。有沒有人發現用戶模型與auth緊密耦合?任何人都認爲django的用戶模型與auth緊密耦合?

背景:當你第一次實現Django的身份驗證,包括模塊django.contrib.auth

這將在幾個車型,如用戶,組,信息等帶來讓我們專注於用戶模式,因爲這是在任何網站中最重要的表格之一。

總之用戶表具有這些字段

用戶

  • 用戶名MAX_LENGTH 30,獨特,[字母,數字,下劃線]
  • 密碼MAX_LENGTH 75
  • 電子郵件MAX_LENGTH 75
  • ...和大約8個其他有用的字段,如first_name,last_name等。

目標:

我想刪除用戶名和使用電子郵件作爲登錄的所有用戶。這是很多網站現在使用的非常簡單的請求。

我不想猴子修補核心代碼,因爲這會使得後續升級變得更加困難。這意味着修改用戶模型是不可能的。我只想做一些簡單而基本的事情,我希望有幾個框架可以做,所以讓我解釋一下Django是如何做到這一點的。

添加新的字段到用戶模式

Django文檔說,使用創建另一個表並插入場那裏。用戶表和配置文件表之間將有一對一的關係。 例如。 如果您想要將圖像字段添加到每個用戶,請將其添加到配置文件表。每次都進行連接查詢。他們甚至指定了一個常量來告訴框架使用哪個表: AUTH_PROFILE_MODULE ='accounts.UserProfile' 我不認爲最好的做法是每次我想要一個應該屬於的字段到用戶表。

另一種選擇是使用函數add_to_class。 Django社區表示,在主類之外定義新字段並不好,因爲添加方法的其他開發人員不會知道所有數據成員。

編輯老油田

中的驗證模塊不會對兩個領域的檢查用戶名和哈希密碼。看上面的表格,我需要改變用戶名模型來接受這些屬性。長度爲75,包含電子郵件的所有有效字符。 Django建議我檢查電子郵件字段。出現

兩個問題,如果我使用的電子郵件領域權威性地反對: 我需要寫在一個恆定AUTHENTICATION_BACKEND使用一個新的類,所以它會針對電子郵件字段中,我有一個名爲用戶名的未使用的字段。

添加新的方法

在MVC/MTV設計原理是利用脂肪模型瘦控制器。由於模型是在auth中聲明的,我不確定應該如何添加在用戶模型的字段上起作用的方法。由於django建議使用Profile模型,我想他們必須去那裏。

擴展User類

一個小的煩惱是,我不能使用名稱「用戶」,而是必須使用「用戶」或「帳戶」。更大的一個是我認爲認證不會識別這個新模塊。這意味着我將不得不重寫一堆存在的功能。這個不會打擾我,因爲這是我希望在其他框架中做的事情。

任何意見表示讚賞。如果我不是真的有興趣使用django,我不會問所有這些問題並尋找解決方案。

+0

Django緩存用戶配置文件,所以它只會執行第一個配置文件訪問的連接查詢。 – gorsky 2010-09-16 10:51:47

回答

4

我同意,Django的不斷clinginess的權威性模型是荒謬的。我的工作要求我創建超級可擴展和非常高負載的站點,有時需要用戶身份驗證和djano的身份驗證模型+權限與此不符。

幸運的是,替換並不難。

首先,創建一個自定義用戶模型。

class User(models.Model): 
    ...fields... 
    #Define some interface methods to be compatible. 
    def get_and_delete_messages(self): 
    def is_active(self): 
    def is_anonymous(self): 
    def is_authenticated(self): 
    def is_staff(self): 
    def has_perm(self, perm_list): 

其次,創建自己的身份驗證後端。

class LocalAccount(object): 
    """ 
    This checks our local user DB for authentication 
    """ 
    def authenticate(self, username=None, password=None): 
     try: 
      user = User.objects.get(alias=username) 
      if user.check_password(password): 
       return user 
     except User.DoesNotExist: 
      return None 

    def get_user(self, user_id): 
     try: 
      return User.objects.select_related().get(pk=user_id) 
     except User.DoesNotExist: 
      return None 

#settings.py 
AUTHENTICATION_BACKENDS = (
    'helpers.auth.LocalAccount', 
) 

這應該解決大部分的問題,我甚至不認爲所有的你會發現在django.contrib.auth.User方法是必要的,我建議您嘗試一下。

這裏的一個問題是,管理員可能會開始婊子,幸運的是,使用簡單的python繼承也很容易修補。這是另一個問題,雖然:)

1

在一天結束時,您的項目的auth後端需要某種存儲身份驗證憑據。認爲默認 auth後端緊密耦合到User模型在這方面並不奇怪。如果您編寫自己的身份驗證後端,用戶模型替換自己的定義很容易,如I have in the past

+0

鏈接已死,你能發佈一個工作嗎? – adamJLev 2010-05-13 18:49:27

+0

你已經在你的模型中設定了默認的'User'。看起來像現在你不能只使用_your own_ user模型定義(例如,沒有'username'和唯一的'email'),因爲Django和一些應用程序,如django-openid-auth,依賴於'User''實施細節。 – Tony 2011-02-25 05:02:13

0

我創建了我的配置文件模型並使用AUTH_PROFILE_MODULE,因此我可以完全控制我的模型,我可以修改字段,添加方法等。現在我正在考慮使用緩存並編寫將從緩存中獲取配置文件的中間件if可能。

登陸使用電子郵件,你可以寫很簡單的身份驗證後端:

from django.contrib.auth.models import User 
from django.contrib.auth.backends import ModelBackend 

class EmailModelBackend(ModelBackend): 
    def authenticate(self, username=None, password=None): 
     try: 
      user = User.objects.get(email=username) 
      if user.check_password(password): 
       return user 
     except User.DoesNotExist: 
      return None 
相關問題