Django Social Auth - 尝试发送电子邮件时没有足够的值来解压

Django Social Auth - Not Enough Values To Unpack When Trying To Send Email

我正在使用 Django-Python Social Auth 应用程序,我正在尝试扩展我的管道,以便当用户使用 Facebook 注册时,他们会同时注册到我的 Mailchimp 邮件列表(并发送电子邮件进行验证)。如果用户使用传统输入法注册但不是通过社交 auth.and 返回此错误,则此方法可以正常工作:

ValueError at /oauth/complete/facebook/ not enough values to unpack (expected 2, got 1)

这里是完整的堆栈跟踪:

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py" in inner
  35.             response = get_response(request)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\views\decorators\csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_django\utils.py" in wrapper
  49.             return func(request, backend, *args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_django\views.py" in complete
  33.                        *args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_core\actions.py" in do_complete
  41.         user = backend.complete(user=user, *args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_core\backends\base.py" in complete
  40.         return self.auth_complete(*args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_core\utils.py" in wrapper
  252.             return func(*args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_core\backends\facebook.py" in auth_complete
  111.         return self.do_auth(access_token, response, *args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_core\backends\facebook.py" in do_auth
  153.         return self.strategy.authenticate(*args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_django\strategy.py" in authenticate
  107.         return authenticate(*args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\auth\__init__.py" in authenticate
  70.             user = _authenticate_with_backend(backend, backend_path, request, credentials)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\auth\__init__.py" in _authenticate_with_backend
  116.     return backend.authenticate(*args, **credentials)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_core\backends\base.py" in authenticate
  80.         return self.pipeline(pipeline, *args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_core\backends\base.py" in pipeline
  83.         out = self.run_pipeline(pipeline, pipeline_index, *args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_core\backends\base.py" in run_pipeline
  112.             func = module_member(name)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\social_core\utils.py" in module_member
  57.     mod, member = name.rsplit('.', 1)

Exception Type: ValueError at /oauth/complete/facebook/
Exception Value: not enough values to unpack (expected 2, got 1)

我的管道是这样的:

SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.auth_allowed',
    'social_core.pipeline.social_auth.social_user',
    'social_core.pipeline.user.get_username',
    'social_core.pipeline.social_auth.associate_by_email',  # <--- enable this one
    'social_core.pipeline.user.create_user',
    'social_core.pipeline.social_auth.associate_user',
    'sendsub',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
)

你可以看到我添加了一个基于此函数的 sendsub 函数---并且有点模仿 off this page here

def sendsub(backend, user, response, *args, **kwargs):
    profile = user.get_profile()
    email = profile.email
    thread = threading.Thread(target=self.run, args=())
    thread.daemon = True                     
    thread.start()                                 

    def run(self):
        API_KEY = settings.MAILCHIMP_API_KEY
        LIST_ID = settings.MAILCHIMP_SUBSCRIBE_LIST_ID
        api = mailchimp.Mailchimp(API_KEY)
        try:
            api.lists.subscribe(LIST_ID, {'email': self.email})
        except:
            return False

同样,这个 sendsub 函数在应用于我的常规注册页面用户模型时正常工作。这是函数(略有不同)。

class SendSubscribeMail(object):
    def __init__(self, email):
        self.email = email
        thread = threading.Thread(target=self.run, args=())
        thread.daemon = True                     
        thread.start()                                 

    def run(self):
        API_KEY = settings.MAILCHIMP_API_KEY
        LIST_ID = settings.MAILCHIMP_SUBSCRIBE_LIST_ID
        api = mailchimp.Mailchimp(API_KEY)
        try:
            api.lists.subscribe(LIST_ID, {'email': self.email})
        except:
            return False

好的,错误本身来自社交身份验证。但那是因为你没有给它正确的数据。

mod, member = name.rsplit('.', 1)

它试图将名称一分为二,名称中没有点,因此您无法将其分成两部分。所以不可能赋值给mod和member。现在我们知道了问题所在,但要解决它还有很长的路要走。第一步是确定罪魁祸首。我会说它就在这里。

thread = threading.Thread(target=self.run, args=())
thread.daemon = True                     
thread.start()   

在 Web 应用程序中创建自己的线程是一件非常危险的事情。您应该同步执行此任务,或者您应该委托给任务队列并让它完全异步发生。

SOCIAL_AUTH_PIPELINE中的条目应该是导入路径的形式,在这种情况下会导致错误,因为sendsub不是正确的导入路径,您需要指定它定义的模块像 module.sendsub.

为了验证导入路径是否正确,您应该能够在 django shell 中以 import module.sendsub 的形式 运行 相同,它应该会成功导入它.

希望这还不算太晚。但在 settings.py 中,确保 AUTHENTICATION_BACKENDS 后面有一个逗号,否则它会被视为字符串,因此会导致错误。