MultipleObjects Возврат с помощью .filter ()? - PullRequest
0 голосов
/ 24 января 2012

Я пишу пользовательский бэкэнд аутентификации для переноса старых пользователей на новый сайт django, работающий на Django 1.3.1. Причина, по которой я должен сделать это, заключается в двух аспектах: один пользователь проходит проверку подлинности с использованием неуникальных адресов электронной почты. И у меня есть только хэш md5 их паролей.

У меня есть модель под названием LegacyUser с полями, называемыми login_email и login_password (из старого дизайна базы данных)

Вот мой сервер аутентификации:

from django.contrib.auth.models import User, check_password
from webshipping.accounts.models import LegacyUser, UserProfile
from hashlib import md5

# see https://docs.djangoproject.com/en/1.3/topics/auth/
# and http://query7.com/django-authentication-backends
class AccountBackend:
    supports_object_permissions = False
    supports_anonymous_user = False
    supports_inactive_user = False

    def authenticate(self, username=None, password=None):
        users = User.objects.filter(email=username)
        for user in users:
            pwd_valid = check_password(password, user.password)
            if pwd_valid:
                return user
        try:
            md5hash = md5(password).hexdigest()
            lu = LegacyUser.objects.filter(login_email=username).filter(login_password=md5hash)
            if lu == []:
                return None

            user = User.objects.create_user(lu[0].login_email, lu[0].login_email, password)
            (first, sep, last) = lu[0].login_realname.rpartition(" ");
            user.first_name = first
            user.last_name = last
            p = user.get_profile()
            p.language = lu[0].login_language
            p.save()
            user.save()
            return user

        except LegacyUser.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Проблема в том, что когда я звоню

LegacyUser.objects.filter(login_email=username).filter(login_password=md5hash) 

бросает:

get() returned more than one LegacyUser -- it returned 3! Lookup parameters were {'login_email': u'test'}

Это именно то, что я хочу, я хочу, чтобы все экземпляры LegacyUser с этой конкретной комбинацией электронной почты и пароля, чтобы я мог объединить их с одним новым пользователем django.

Если я обновлю страницу 2-3 раза, она пройдет и создаст объект User, и все будущие логины будут работать как положено.

Мой вопрос: чего мне не хватает? Разве фильтр не должен возвращать несколько объектов?

Вот полный след:

Environment:


Request Method: POST
Request URL: http://192.168.100.65/accounts/login/?next=/

Django Version: 1.3.1
Python Version: 2.7.2
Installed Applications:
['django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django_extensions',
 'webshipping.accounts',
 'webshipping.addressbooks',
 'webshipping.shipments',
 'webshipping.transports']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
  93.                     response = view_func(request, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
  79.         response = view_func(request, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/django/contrib/auth/views.py" in login
  35.         if form.is_valid():
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in is_valid
  121.         return self.is_bound and not bool(self.errors)
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _get_errors
  112.             self.full_clean()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in full_clean
  268.         self._clean_form()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _clean_form
  296.             self.cleaned_data = self.clean()
File "/usr/lib/python2.7/dist-packages/django/contrib/auth/forms.py" in clean
  85.             self.user_cache = authenticate(username=username, password=password)
File "/usr/lib/python2.7/dist-packages/django/contrib/auth/__init__.py" in authenticate
  55.             user = backend.authenticate(**credentials)
File "/usr/local/lib/link/dev/webshipping/../webshipping/accounts/backends.py" in authenticate
  20.                     lu = LegacyUser.objects.filter(login_email=username).filter(login_password=md5hash)
File "/usr/lib/python2.7/dist-packages/django/db/models/manager.py" in get
  132.         return self.get_query_set().get(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/django/db/models/query.py" in get
  351.                 % (self.model._meta.object_name, num, kwargs))

Exception Type: MultipleObjectsReturned at /accounts/login/
Exception Value: get() returned more than one LegacyUser -- it returned 3! Lookup parameters were {'login_email': u'test'}
...