2010-06-14 5 views
0

J'ai des difficultés à faire en sorte que mon gestionnaire de modèle se comporte correctement lorsque j'utilise l'interface d'administration. Au fond, j'ai deux modèles:Gestionnaire de modèle Django use_for_related_fields et relations 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) 
    . . . 

Et j'ai une classe EmployeeManager qui remplace la méthode get(), quelque chose comme ceci:

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. 

Fondamentalement, l'idée est d'avoir des objets Employee automatiquement créés à partir de la informations dans Active Directory si elles n'existent pas déjà dans la base de données. Cela fonctionne bien avec mon code d'application, mais lorsque j'ai essayé de créer une page d'administration Django pour le modèle Eotm, les choses n'étaient pas très agréables. J'ai remplacé le widget par défaut pour les champs ForeignKey avec un widget TextInput afin que les utilisateurs puissent taper un nom d'utilisateur (puisque username est la clé primaire). En théorie, cela devrait appeler EmployeeManager.get(username='whatever'), qui renverrait un Employee exactement comme le gestionnaire par défaut ou en créer un et le retourner s'il n'en existait pas déjà un. Le problème est que mon manager n'est pas utilisé.

Je ne trouve rien dans la documentation de Django à propos de l'utilisation de classes Manager personnalisées et du site Admin, à part le generic manager documentation. J'ai trouvé un blog entry qui parlait de spécifier un gestionnaire personnalisé pour les classes ModelAdmin, mais cela n'aide pas vraiment car je ne veux pas changer le modèle représenté par une classe ModelAdmin, mais à laquelle elle est liée.

+0

Note non liée: Je ne recommanderais pas de surcharger le comportement de get dans votre EmployeeManager. A la place, je remplacerais la fonction get_or_create. Cela fait exactement ce dont vous parlez ici. Il peut y avoir des cas où vous voulez obtenir l'enregistrement exact mais que vous ne voulez pas nécessairement le créer s'il n'existe pas. Vous pouvez appeler get_or_create partout où vous voulez créer automatiquement, comme ceci: 'emp, created = Employee.objects.get_or_create (username = 'johndoe')'. Assurez-vous simplement qu'il renvoie l'objet * et * 'True' (si créé à partir de zéro) ou' False' (s'il existait déjà). –

+0

J'ai évité d'utiliser la méthode 'get_or_create' car je ne voulais pas laisser entendre que le code pouvait créer un objet' Employee'. Je veux également que le modèle 'Employee' se comporte exactement comme les autres modèles, mais tire ses informations du répertoire au lieu de la base de données. – AdmiralNemo

+0

Donc, fondamentalement, il y a trois scénarios: 1) l'enregistrement des employés existe; 2) il n'existe pas; ou 3) il n'existe pas et aucun enregistrement LDAP correspondant n'existe (et donc ne crée pas un nouvel employé.) Dans ce cas, je recommanderais de ne pas utiliser 'get', sauf si vous êtes certain à 100% –

Répondre

0

Je ne peux pas être comprendre ce que vous essayez de faire, mais vous pouvez utiliser un formulaire personnalisé pour votre modèle 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) 

que, en théorie, devrait fonctionner. Je ne l'ai pas testé.

+0

J'ai essayé cela, mais la méthode 'clean_employee' ne s'est pas appelée.J'ai ajouté un autre champ' foo' comme test et j'ai créé une méthode 'clean_foo', qui est appelée par la suite – AdmiralNemo

+0

Bon, ça marche si je spécifier manuellement l'attribut 'employee' du e 'EotmAdminForm' au lieu de le laisser être ajouté automatiquement. Merci de votre aide. – AdmiralNemo

Questions connexes