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.
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à). –
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
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% –