Django-Allauth出现MultipleObjectsReturned异常的问题排查
问题解决:Django-Allauth多站点下Github登录触发MultipleObjectsReturned异常
问题背景
用Django Sites模型区分localhost:8000和productive_server.de两个环境,数据库里已经给两个站点分别配置了对应SITE_ID的Github SocialApp,但登录时还是抛出MultipleObjectsReturned异常。
问题根因
排查后发现是DefaultSocialAccountAdapter的list_apps方法存在逻辑漏洞:当没有传入request参数时,不会按site_id过滤SocialApp,导致返回两个同类型的provider实例,触发异常。进一步追踪错误栈,发现是在complete_social_login调用sociallogin.lookup()时丢失了request参数,最终引发问题,这应该是django-allauth的一个bug。
临时修复方案
自定义一个SocialAccountAdapter,重写list_apps方法,强制按当前站点的SITE_ID过滤,即使没有传入request也能正确筛选:
# 在你的app目录下创建adapter.py文件 from allauth.socialaccount.adapter import DefaultSocialAccountAdapter from django.conf import settings class CustomSocialAccountAdapter(DefaultSocialAccountAdapter): def list_apps(self, request, provider): apps = super().list_apps(request, provider) # 强制按当前site过滤,兼容无request的场景 if not request and hasattr(settings, 'SITE_ID'): apps = apps.filter(sites__id=settings.SITE_ID) return apps
然后在settings.py里配置使用这个自定义Adapter:
SOCIALACCOUNT_ADAPTER = '你的应用名称.adapter.CustomSocialAccountAdapter'
如果不想修改源码,不建议直接去补全sociallogin.lookup()的request参数,自定义Adapter是更稳妥的兼容方案。
内容的提问来源于stack exchange,提问作者Razenstein
相关产品推荐
相关产品推荐

