Thursday, February 28, 2013

Re: Problem with two databases

On Thu, Feb 28, 2013 at 1:45 PM, MoonWolf <moonwolf.django@gmail.com> wrote:
> I'm making simple application to manage equipment. I've
> used django-ldapdb
> (http://opensource.bolloretelecom.eu/projects/django-ldapdb/) for user
> management (not for authentication, for which i'm using PAM). After
> heavy googling i've managed to connect all this together - LDAP as
> second database), so i can use LDAP-based users as owners of equipment
> (here are most important parts of models):
>
> class LdapUser(ldapdb.models.Model):
> """
> Class for representing an LDAP user entry.
> """
> class Meta:
> managed = False
> [...]
> full_name = CharField(db_column='cn')
> username = CharField(db_column='uid', primary_key=True)
>
> class Equipment(models.Model):
> number = models.CharField(unique=True, max_length=13)
> state = models.ForeignKey(State)
> model = models.CharField(max_length=255)
> owner = ForeignKeyAcrossDb(LdapUser)
> description = models.CharField(blank=True, max_length=255)
> type = models.ForeignKey(Type)
> place = models.ForeignKey(Place)
>
> def __unicode__(self):
> return u"%s (%s)" % (self.type, self.number)
>
> i googled out ForeignKeyAcrossDb, it's not my code. Also i have googled
> out database router (for main database):
>
> class DefRouter(object):
> def db_for_read(self, model, **hints):
> if model._meta.app_label == 'equipment_control':
> return 'default'
> return None
>
> def db_for_write(self, model, **hints):
> if model._meta.app_label == 'equipment_control':
> return 'default'
> return None
>
> def allow_relation(self, obj1, obj2, **hints):
> if obj1._meta.app_label == 'equipment_control' or
> obj2._meta.app_label == 'equipment_control':
> return True
> return None
>
> def allow_syncdb(self, db, model):
> if db == 'default':
> if model._meta.app_label == 'equipment_control':
> return True
> elif model._meta.app_label == 'equipment_control':
> return False
> return None
>
> And basically it works - i can edit users and also i can use LDAP-based
> users in my Equipments. But there are some issues:
>
> * i can't filter Equipments using 'owner' field:
> Equipment.objects.filter(owner__full_name__contains="name")
> ERROR: relation "equipment_control_ldapuser" does not exists
> (which is true of course, because engine tries to find name in database
> - postgresql in my example)
>
> * i can't customize Admin panel - for example (in admin.py):
>
> class EquipmentModelAdmin(reversion.VersionAdmin):
> list_display = ("owner", "type", "number", "description")
>
> and i have "ERROR: relation "equipment_control_ldapuser" does not
> exists" error.
>
> Is there any possibility to use LDAP transparently? Or maybe some
> workaround exists? I'm pretty new to Django (it's my first "true"
> application) and my knowledge of python is not very high also, so i
> can't figure out any solution. Thanks in advance for any help.
>

I'd do this in a different way, I'd have the user model in the main
database, with an attribute named 'cn', reflecting their LDAP cn.
Authentication is done against LDAP, but using an LDAP auth backend,
rather than trying to pretend LDAP is a django-supported DB. (In fact,
where I have done LDAP auth, I have done it exactly like this)

Any LDAP properties that you require could be added as python
properties to the user model, looking up the info in LDAP on demand,
perhaps caching it.

You then do not need any complex routing or multi DB weirdness.

Cheers

Tom

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.

No comments:

Post a Comment