X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=ldapdb%2Fmodels%2Fbase.py;h=cdc44e21fc4e32869dc0c49043951a88f130f102;hb=81037a75f672596982475a7081946bfd9b4fd286;hp=1e47a53298da5e9036b95a4fb1e2a0f564231d22;hpb=20e2c869ddee0fc85878c94c60512040b5c563ab;p=matthijs%2Fupstream%2Fdjango-ldapdb.git diff --git a/ldapdb/models/base.py b/ldapdb/models/base.py index 1e47a53..cdc44e2 100644 --- a/ldapdb/models/base.py +++ b/ldapdb/models/base.py @@ -24,6 +24,7 @@ import ldap import logging import django.db.models +from django.db.models import signals import ldapdb from ldapdb.models.query import QuerySet @@ -58,6 +59,10 @@ class Model(django.db.models.base.Model): dn = django.db.models.fields.CharField(max_length=200) + # meta-data + base_dn = None + object_classes = ['top'] + def __init__(self, *args, **kwargs): super(Model, self).__init__(*args, **kwargs) self.saved_pk = self.pk @@ -78,7 +83,7 @@ class Model(django.db.models.base.Model): """ Build the Distinguished Name for this entry. """ - return "%s,%s" % (self.build_rdn(), self._meta.dn) + return "%s,%s" % (self.build_rdn(), self.base_dn) raise Exception("Could not build Distinguished Name") def delete(self): @@ -87,11 +92,13 @@ class Model(django.db.models.base.Model): """ logging.debug("Deleting LDAP entry %s" % self.dn) ldapdb.connection.delete_s(self.dn) + signals.post_delete.send(sender=self.__class__, instance=self) def save(self): - # create a new entry if not self.dn: - entry = [('objectClass', self._meta.object_classes)] + # create a new entry + record_exists = False + entry = [('objectClass', self.object_classes)] new_dn = self.build_dn() for field in self._meta.local_fields: @@ -103,38 +110,51 @@ class Model(django.db.models.base.Model): logging.debug("Creating new LDAP entry %s" % new_dn) ldapdb.connection.add_s(new_dn, entry) - + # update object self.dn = new_dn - self.saved_pk = self.pk - return - # update an existing entry - modlist = [] - orig = self.__class__.objects.get(pk=self.saved_pk) - for field in self._meta.local_fields: - if not field.db_column: - continue - old_value = getattr(orig, field.name, None) - new_value = getattr(self, field.name, None) - if old_value != new_value: - if new_value: - modlist.append((ldap.MOD_REPLACE, field.db_column, new_value)) - elif old_value: - modlist.append((ldap.MOD_DELETE, field.db_column, None)) - - if not len(modlist): - logging.debug("No changes to be saved to LDAP entry %s" % self.dn) - return - - # handle renaming - new_dn = self.build_dn() - if new_dn != self.dn: - logging.debug("Renaming LDAP entry %s to %s" % (self.dn, new_dn)) - ldapdb.connection.rename_s(self.dn, self.build_rdn()) - self.dn = new_dn - - logging.debug("Modifying existing LDAP entry %s" % self.dn) - ldapdb.connection.modify_s(self.dn, modlist) + else: + # update an existing entry + record_exists = True + modlist = [] + orig = self.__class__.objects.get(pk=self.saved_pk) + for field in self._meta.local_fields: + if not field.db_column: + continue + old_value = getattr(orig, field.name, None) + new_value = getattr(self, field.name, None) + if old_value != new_value: + if new_value: + modlist.append((ldap.MOD_REPLACE, field.db_column, new_value)) + elif old_value: + modlist.append((ldap.MOD_DELETE, field.db_column, None)) + + if len(modlist): + # handle renaming + new_dn = self.build_dn() + if new_dn != self.dn: + logging.debug("Renaming LDAP entry %s to %s" % (self.dn, new_dn)) + ldapdb.connection.rename_s(self.dn, self.build_rdn()) + self.dn = new_dn + + logging.debug("Modifying existing LDAP entry %s" % self.dn) + ldapdb.connection.modify_s(self.dn, modlist) + else: + logging.debug("No changes to be saved to LDAP entry %s" % self.dn) + + # done self.saved_pk = self.pk + signals.post_save.send(sender=self.__class__, instance=self, created=(not record_exists)) + + @classmethod + def scoped(base_class, base_dn): + """ + Returns a copy of the current class with a different base_dn. + """ + import new + import re + name = "%s_%s" % (base_class.__name__, re.sub('[=,]', '_', base_dn)) + new_class = new.classobj(name, (base_class,), {'base_dn': base_dn, '__module__': base_class.__module__}) + return new_class