2010-06-14 50 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