Python 使用.filter()返回多个对象?
我正在编写一个自定义身份验证后端,用于将legacyusers迁移到运行在django 1.3.1上的新django站点。 我必须这样做的原因有两个,一个是使用非唯一电子邮件地址对用户进行身份验证。我只有他们密码的md5散列 我有一个名为LegacyUser的模型,其字段名为login_email和login_password(来自旧数据库设计) 以下是我的身份验证后端:Python 使用.filter()返回多个对象?,python,django,django-models,Python,Django,Django Models,我正在编写一个自定义身份验证后端,用于将legacyusers迁移到运行在django 1.3.1上的新django站点。 我必须这样做的原因有两个,一个是使用非唯一电子邮件地址对用户进行身份验证。我只有他们密码的md5散列 我有一个名为LegacyUser的模型,其字段名为login_email和login_password(来自旧数据库设计) 以下是我的身份验证后端: from django.contrib.auth.models import User, check_password fr
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次,它就会通过并创建用户对象,所有未来的登录都会按预期工作
我的问题是,我错过了什么?过滤器不应该返回多个对象吗
以下是完整的回溯:
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'}
我不确定,但您的错误消息说,
LegacyUser
有3个实例具有相同的“登录电子邮件”。现在你说你想“组合”他们的密码。这是否意味着您将允许使用3个密码中的任何一个登录到此帐户?您是否计划在数据库中使用列表/数组作为密码字段?我有一个旧网站,我想迁移该网站的用户。用户被绑定到多个组中,每个组成员在LegacyUser
中都有记录。因此,每个LegacyUser
login\u电子邮件都是非唯一的,每个用户都通过电子邮件和密码进行标识。所以我希望所有3个(密码相同)都是一个用户。这实际上似乎是服务器与代码不同步。您最初是否编写了get
,然后将其更改为filter
?如果是这样,请删除所有.pyc
文件并重新启动服务器。我认为你是对的。。。我想我发现了这个问题,我正在通过mod_wsgi在apache上运行这个站点。。apache/mod_wsgi似乎存储了站点的某种缓存。正如我重新启动apache时一样,它自己解决了问题。除非您要求,否则mod_wsgi不会使用新代码。您可以触摸.wsgi文件(首选方式)或重新启动Apache。