我在我的项目中使用
python-social-auth和电子邮件注册.对于用户模型,我使用AbstractBaseUser的子类:
class User(AbstractBaseUser): USERNAME_FIELD = 'email' AUTH_USER_MODEL = 'userprofile.User'
但是,如果用他的电子邮件注册的用户(demo@demo.com)和密码尝试使用与同一电子邮件地址关联的Facebook帐户登录,则会收到以下错误:
IntegrityError at /social/complete/facebook/ duplicate key value violates unique constraint "userprofile_user_email_key" DETAIL: Key (email)=(demo@demo.com) already exists. /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/core/handlers/base.py in get_response response = wrapped_callback(request,*callback_args,**callback_kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/views/decorators/csrf.py in wrapped_view return view_func(*args,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/apps/django_app/utils.py in wrapper return func(request,backend,*args,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/apps/django_app/views.py in complete redirect_name=REDIRECT_FIELD_NAME,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/actions.py in do_complete *args,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/strategies/base.py in complete return self.backend.auth_complete(*args,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/backends/facebook.py in auth_complete return self.do_auth(access_token,response,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/backends/facebook.py in do_auth return self.strategy.authenticate(*args,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/strategies/django_strategy.py in authenticate return authenticate(*args,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/contrib/auth/__init__.py in authenticate user = backend.authenticate(**credentials) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/backends/base.py in authenticate return self.pipeline(pipeline,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/backends/base.py in pipeline out = self.run_pipeline(pipeline,pipeline_index,**kwargs) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/backends/base.py in run_pipeline result = func(*args,**out) or {} ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/pipeline/user.py in user_details strategy.storage.user.changed(user) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/social/storage/django_orm.py in changed user.save() ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/models/base.py in save force_update=force_update,update_fields=update_fields) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/models/base.py in save_base updated = self._save_table(raw,cls,force_insert,force_update,using,update_fields) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/models/base.py in _save_table forced_update) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/models/base.py in _do_update return filtered._update(values) > 0 ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/models/query.py in _update return query.get_compiler(self.db).execute_sql(None) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/models/sql/compiler.py in execute_sql cursor = super(sqlUpdateCompiler,self).execute_sql(result_type) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/models/sql/compiler.py in execute_sql cursor.execute(sql,params) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/debug_toolbar/panels/sql/tracking.py in execute return self._record(self.cursor.execute,sql,params) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/debug_toolbar/panels/sql/tracking.py in _record return method(sql,params) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/backends/util.py in execute return super(CursorDebugWrapper,self).execute(sql,params) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/backends/util.py in execute return self.cursor.execute(sql,params) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/utils.py in __exit__ six.reraise(dj_exc_type,dj_exc_value,traceback) ... /Users/vera/.virtualenvs/app/lib/python2.7/site-packages/django/db/backends/util.py in execute return self.cursor.execute(sql,params) ...
当有人注册他的Facebook帐户,然后登录一切正常.当他注册他的电子邮件时我会出现问题(我正在使用django-registration),因此我们有一个User(但不是UserSocialAuth)实例,然后我们尝试使用与他相同的电子邮件地址关联的Facebook帐户登录.
解决方法
问题解决了.问题在于管道中的顺序必须如下:
DEFAULT_AUTH_PIPELINE = ( 'social.pipeline.social_auth.social_details','social.pipeline.social_auth.social_uid','social.pipeline.social_auth.auth_allowed','social.pipeline.social_auth.social_user','social.pipeline.user.get_username','social.pipeline.mail.mail_validation','social.pipeline.social_auth.associate_by_email','social.pipeline.user.create_user','social.pipeline.social_auth.associate_user','social.pipeline.social_auth.load_extra_data','social.pipeline.user.user_details' )
非常感谢图书馆的作者,他帮助解决了这个问题.