views:

46

answers:

1

I am having trouble getting my model manager to behave correctly when using the Admin interface. Basically, I have two models:

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)
    . . .

And I have an EmployeeManager class that overrides the get() method, something like this:

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.

Basically, the idea is to have Employee objects automatically created from the information in Active Directory if they don't already exist in the database. This works well from my application code, but when I tried to create a Django admin page for the Eotm model, things weren't so nice. I replaced the default widget for ForeignKey fields with a TextInput widget so users could type a username (since username is the primary key). In theory, this should call EmployeeManager.get(username='whatever'), which would either return an Employee just like the default manager or create one and return it if one didn't already exist. The problem is, my manager is not being used.

I can't find anything in the Django documentation about using custom Manager classes and the Admin site, aside from the generic manager documentation. I did find a blog entry that talked about specifying a custom manager for ModelAdmin classes, but that doesn't really help because I don't want to change the model represented by a ModelAdmin class, but one to which it is related.

A: 

I may not be understanding what you're trying to do here, but you could use a custom Form for your Eotm model:

#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)

That, in theory, should work. I haven't tested it.

Jordan Reiter
I tried that, but the `clean_employee` method doesn't get called. I added another field `foo` as a test and created a `clean_foo` method, which does get called though.
AdmiralNemo
Okay, it works if I manually specify the `employee` attribute of the `EotmAdminForm` instead of letting it be automatically added. Thanks for your help.
AdmiralNemo