django_auth_ldap自定义AUTH_USER_MODEL IntegrityError

时间:2014-06-06 11:41:18

标签: python django ldap signals django-auth-ldap

我试图让django_auth_ldap使用自定义用户模型。经过一番努力,我用一个模型创建了新的应用程序:

class MyUser(django.contrib.auth.models.AbstractUser):
    uidNumber = models.IntegerField(unique=True)

在settings.py中我有:

AUTH_USER_MODEL = 'test_ldap.MyUser' 
AUTH_LDAP_ALWAYS_UPDATE_USER = False
AUTH_LDAP_USER_ATTR_MAP = {"first_name": "firstName", "last_name": "sn", "email": "mail", "uidNumber": "uidNumber"}
AUTH_LDAP_PROFILE_ATTR_MAP = {"home_directory": "homeDirectory", "uidNumber": "uidNumber"}
AUTH_LDAP_BIND_DN = ""
AUTH_LDAP_BIND_PASSWORD = ""
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=People,ou=Main,o=TECH",
    ldap.SCOPE_SUBTREE, "(uid=%(user)s)")

作为登录页面:

urlpatterns += patterns('', 
     url(r'^login/$', 'django.contrib.auth.views.login', {
    'template_name': 'login.tmpl'
     }),
    (r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}),
)

manage.py syncdb成功。

登录后,我有 NOT NULL约束失败:test_ldap_myuser.uidNumber 。看起来LDAP后端试图仅使用默认的类用户数据来保存用户。

Environment:


Request Method: POST
Request URL: http://localhost:8000/login/

Django Version: 1.6.5
Python Version: 2.7.5
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'test_ldap')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
112.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
75.             return view(request, *args, **kwargs)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
99.                     response = view_func(request, *args, **kwargs)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
52.         response = view_func(request, *args, **kwargs)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/contrib/auth/views.py" in login
36.         if form.is_valid():
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/forms/forms.py" in is_valid
129.         return self.is_bound and not bool(self.errors)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/forms/forms.py" in errors
121.             self.full_clean()
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/forms/forms.py" in full_clean
274.         self._clean_form()
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/forms/forms.py" in _clean_form
300.             self.cleaned_data = self.clean()
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/contrib/auth/forms.py" in clean
189.                                            password=password)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/contrib/auth/__init__.py" in authenticate
49.             user = backend.authenticate(**credentials)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django_auth_ldap/backend.py" in authenticate
158.         user = ldap_user.authenticate(password)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django_auth_ldap/backend.py" in authenticate
330.             self._get_or_create_user()
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django_auth_ldap/backend.py" in _get_or_create_user
529.         self._user, created = self.backend.get_or_create_user(username, self)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django_auth_ldap/backend.py" in get_or_create_user
223.         return model.objects.get_or_create(**kwargs)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/manager.py" in get_or_create
154.         return self.get_queryset().get_or_create(**kwargs)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/query.py" in get_or_create
391.                     six.reraise(*exc_info)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/query.py" in get_or_create
383.                     obj.save(force_insert=True, using=self.db)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/base.py" in save
545.                        force_update=force_update, update_fields=update_fields)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/base.py" in save_base
573.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/base.py" in _save_table
654.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
687.                                using=using, raw=raw)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/manager.py" in _insert
232.         return insert_query(self.model, objs, fields, **kwargs)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/query.py" in insert_query
1514.     return query.get_compiler(using=using).execute_sql(return_id)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
903.             cursor.execute(sql, params)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/backends/util.py" in execute
69.             return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/backends/util.py" in execute
53.                 return self.cursor.execute(sql, params)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/utils.py" in __exit__
99.                 six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/backends/util.py" in execute
53.                 return self.cursor.execute(sql, params)
File "/home/moonwolf/Dokumenty/projects/python/virtualenv/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py" in execute
451.         return Database.Cursor.execute(self, query, params)

Exception Type: IntegrityError at /login/
Exception Value: NOT NULL constraint failed: test_ldap_myuser.uidNumber

所以我尝试使用 populate_user 信号,如文档中所述:

@receiver(django_auth_ldap.backend.populate_user)
    def ldap_populate_user_receiver(sender, user=None, ldap_user=None, **kwargs):
        print "Signal received"
        # set uidNumber accordingly

(我把它放在models.py中)

但是这个功能没有输出(它根本没有被调用)。当我将用户模型更改回默认用户时,一切正常(并且从信号输出出现 - 在这种情况下,当然不需要改变任何数据)。看起来django试图将数据写入数据库(get_or_create_user())或什么?

我做错了什么?

1 个答案:

答案 0 :(得分:0)

我有点设法解决了这个问题。我使用默认的auth.User并添加了Model with ForeignKey指向它。在这个模型中,我将拥有我需要的额外属性。通过与LDAP后端的某些同步(例如,在创建新用户的情况下),这应该可行。