2010-06-14 68 views
0

我無法讓我的模型管理器在使用Admin界面時正常運行。基本上,我有兩個型號:Django模型管理器use_for_related_fields和ModelAdmin關係

class Employee(models.Model): 
    objects = models.EmployeeManager() 
    username = models.CharField(max_length=45, primary_key=True) 
    . . . 

class Eotm(models.Model): #Employee of the Month 
    date = models.DateField() 
    employee = models.ForeignKey(Employee) 
    . . . 

而且我有一個EmployeeManager類覆蓋get()方法,像這樣:

class EmployeeManager(models.Manager): 
    use_for_related_fields = True 

    def get(self, *arguments, **keywords): 
     try: 
      return super(EmployeeManager, self).get(*arguments, **keywords) 
     except self.model.DoesNotExist: 
      #If there is no Employee matching query, try an LDAP lookup and create 
      #a model instance for the result, if there is one. 

基本上,這個想法是有從自動創建Employee對象Active Directory中的信息(如果它們尚不存在於數據庫中)。這從我的應用程序代碼運行良好,但是當我嘗試爲Eotm模型創建Django管理頁面時,情況並不是那麼好。我用TextInput小部件替換了ForeignKey字段的默認小部件,以便用戶可以鍵入用戶名(因爲username是主鍵)。理論上,這應該調用EmployeeManager.get(username='whatever'),它會像默認管理器一樣返回Employee,或者創建一個並返回它(如果它不存在的話)。問題是,我的經理沒有被使用。

我在Django文檔中找不到有關使用自定義Manager類和Admin站點(除generic manager documentation之外)的任何內容。我確實找到了一個blog entry,它提到了爲ModelAdmin類指定一個自定義管理器,但這並沒有什麼幫助,因爲我不想更改ModelAdmin類所表示的模型,但它與其相關的模型不同。

+0

無關的說明:我不建議覆蓋獲取您的EmployeeManager中的行爲。相反,我會重寫get_or_create函數。這就是你在這裏討論的。在某些情況下,您想要獲得確切的記錄,但不希望在不存在的情況下創建它。您可以在任何想要自動創建的位置調用get_or_create,如下所示:'emp,created = Employee.objects.get_or_create(username ='johndoe')'。只要確保它返回對象*和*'True'(如果從頭創建)或'False'(如果它已經存在)。 – 2010-06-14 15:38:06

+0

我避免使用'get_or_create'方法,因爲我不想暗示代碼可以創建一個'Employee'對象。我也希望'Employee'模型的行爲與其他模型完全一樣,但是從目錄而不是數據庫中提取信息。 – AdmiralNemo 2010-06-14 16:05:42

+0

所以基本上有三種情況:1)員工記錄存在; 2)它不存在;或者3)它不存在,也不存在匹配的LDAP記錄(因此不會創建一個新的Employee。在這種情況下,我仍然建議不要使用'get',除非你100%確定你總是期望在調用'get'時可能會產生副作用(員工記錄創建) – 2010-06-14 18:17:55

回答

0

我可能不會理解你想在這裏做什麼,而是你可以使用自定義窗體爲您Eotm型號:

#admin.py 
from forms import EotmAdminForm 

class EotmAdmin(models.ModelAdmin): 
    form = EotmAdminForm 


#forms.py 
from django import forms 
from models import Eotm, Employee 

class EotmAdminForm(forms.ModelForm) 
    class Meta: 
     model = Eotm 

    def clean_employee(self): 
     username = self.cleaned_data['employee'] 
     return Employee.get(username=username) 

,從理論上講,應該工作。我沒有測試過它。

+0

我試過了,但是'clean_employee'方法沒有被調用,我添加了另外一個字段'foo'作爲一個測試,並創建了一個'clean_foo'方法,但它確實被調用。 – AdmiralNemo 2010-06-14 16:10:21

+0

好吧,手動指定th的'employee'屬性e'EotmAdminForm'而不是讓它自動添加。謝謝你的幫助。 – AdmiralNemo 2010-06-14 16:33:00