Wednesday, February 25, 2015

Auto create and populate UserProfile in Django 1.7 with django-auth-ldap

To map some extra information of the Active Directory user into my Django's StudentProfile (UserProfile) model (Django 1.7 and django-auth-ldap 1.2.5), I have to call a post_save signal:

In my

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django_auth_ldap.backend import LDAPBackend

class StudentProfile(models.Model):
user = models.OneToOneField(User, related_name="student_profile", related_query_name="profile")
student_number = models.CharField(max_length=255) # Office
class_of = models.CharField(max_length=255) # Description

def create_student_profile(sender, instance, created, **kwargs):
if created:
new_profile = StudentProfile.objects.create(user=instance)
user = LDAPBackend().populate_user(instance.username)
if user:
desc = user.ldap_user.attrs.get("description", [])[0]
office = user.ldap_user.attrs.get("physicalDeliveryOfficeName", [])[0]
new_profile.student_number = office
new_profile.class_of = desc

post_save.connect(create_student_profile, sender=User)

The first time a user log in, an User object will be created along with a StudentProfile object with data initialized from the ldap_user.

This process of mapping UserProfile attribute from LDAP has become complicated like this because Django 1.7 does not support UserProfile (the way I did is just a OneToOne mapping between two models) and django_auth_ldap won't honor any profile-related configuration. So, the only way to automatically generate userprofile from Active Directory is to populate the UserProfile with a post_save signal.