我无法让我的模型管理器在使用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
类所表示的模型,但它与其相关的模型不同。
无关的说明:我不建议覆盖获取您的EmployeeManager中的行为。相反,我会重写get_or_create函数。这就是你在这里讨论的。在某些情况下,您想要获得确切的记录,但不希望在不存在的情况下创建它。您可以在任何想要自动创建的位置调用get_or_create,如下所示:'emp,created = Employee.objects.get_or_create(username ='johndoe')'。只要确保它返回对象*和*'True'(如果从头创建)或'False'(如果它已经存在)。 – 2010-06-14 15:38:06
我避免使用'get_or_create'方法,因为我不想暗示代码可以创建一个'Employee'对象。我也希望'Employee'模型的行为与其他模型完全一样,但是从目录而不是数据库中提取信息。 – AdmiralNemo 2010-06-14 16:05:42
所以基本上有三种情况:1)员工记录存在; 2)它不存在;或者3)它不存在,也不存在匹配的LDAP记录(因此不会创建一个新的Employee。在这种情况下,我仍然建议不要使用'get',除非你100%确定你总是期望在调用'get'时可能会产生副作用(员工记录创建) – 2010-06-14 18:17:55