【问题标题】:from_db_value() missing 1 required positional argument: 'context'from_db_value() 缺少 1 个必需的位置参数:“上下文”
【发布时间】:2020-09-25 12:17:10
【问题描述】:

尝试使用 googleapiclientoauth2client 为 django 创建 google 登录。

我能够打开主页,并成功重定向到谷歌登录。登录后,它会重定向到我收到此错误的主页。

参考link/tutorial

views.py

import httplib2

from googleapiclient.discovery import build
from django.http import HttpResponseBadRequest
from django.http import HttpResponseRedirect
from .models import CredentialsModel
from gfglogin import settings
from oauth2client.contrib import xsrfutil
from oauth2client.client import flow_from_clientsecrets
from oauth2client.contrib.django_util.storage import DjangoORMStorage
from django.shortcuts import render
from httplib2 import Http


def home(request):
    print("*****home*****")
    status = True

    if not request.user.is_authenticated:
        return HttpResponseRedirect('admin')

    storage = DjangoORMStorage(CredentialsModel, 'id', request.user, 'credential')
    credential = storage.get()
    print(f"credential: {credential}")
    print(f"storage: {storage}")

    try:
        access_token = credential.access_token
        resp, cont = Http().request("https://www.googleapis.com/auth/gmail.readonly",
                                    headers={'Host': 'www.googleapis.com',
                                            'Authorization': access_token})
    except:
        status = False
        print('Not Found')

    return render(request, 'index.html', {'status': status})


################################
#   GMAIL API IMPLEMENTATION   #
################################

# CLIENT_SECRETS, name of a file containing the OAuth 2.0 information for this
# application, including client_id and client_secret, which are found
# on the API Access tab on the Google APIs
# Console <http://code.google.com/apis/console>


FLOW = flow_from_clientsecrets(
    settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON,
    scope='https://www.googleapis.com/auth/gmail.readonly',
    redirect_uri='http://127.0.0.1:8080/oauth2callback',
    prompt='consent')


def gmail_authenticate(request):
    print("*****gmail_authenticate*****")
    storage = DjangoORMStorage(CredentialsModel, 'id', request.user, 'credential')
    credential = storage.get()
    print(f"credential: {credential}")
    if credential is None or credential.invalid:
        FLOW.params['state'] = xsrfutil.generate_token(settings.SECRET_KEY,
                                                       request.user)
        authorize_url = FLOW.step1_get_authorize_url()
        return HttpResponseRedirect(authorize_url)
    else:
        http = httplib2.Http()
        http = credential.authorize(http)
        service = build('gmail', 'v1', http=http)
        print('access_token = ', credential.access_token)
        status = True

        return render(request, 'index.html', {'status': status})


def auth_return(request):
    print("*****auth_return*****")
    get_state = bytes(request.GET.get('state'), 'utf8')
    if not xsrfutil.validate_token(settings.SECRET_KEY, get_state,
                                   request.user):
        return HttpResponseBadRequest()
    credential = FLOW.step2_exchange(request.GET.get('code'))
    print(f"credential: {credential}")
    storage = DjangoORMStorage(CredentialsModel, 'id', request.user, 'credential')
    storage.put(credential)
    print(f"storage: {storage}")
    print("access_token: %s" % credential.access_token)
    return HttpResponseRedirect("/")

错误:

System check identified no issues (0 silenced).
June 06, 2020 - 14:38:49
Django version 3.0.7, using settings 'gfglogin.settings'
Starting development server at http://127.0.0.1:8080/
Quit the server with CTRL-BREAK.
[06/Jun/2020 14:39:00] "GET /admin/ HTTP/1.1" 200 3042
*****home*****
credential: None
storage: <oauth2client.contrib.django_util.storage.DjangoORMStorage object at 0x0000014A630EABE0>
Not Found
[06/Jun/2020 14:39:05] "GET / HTTP/1.1" 200 327
*****gmail_authenticate*****
credential: None
[06/Jun/2020 14:39:07] "GET /gmailAuthenticate HTTP/1.1" 302 0
*****auth_return*****
credential: <oauth2client.client.OAuth2Credentials object at 0x0000014A6322BA00>
storage: <oauth2client.contrib.django_util.storage.DjangoORMStorage object at 0x0000014A6322B550>
access_token: ya29.a0AfH6SMBLyCWC3cV4iiMk0jWUJaw8ruUFoBqFTkM5LT2acAc6FelcoADU3tn67RslO-24dKEFqrdp4tcLFVuEIMvmn7cHKeb8XeZ9YNQozRoRSTU6hs-jMA9bHP10epw1ImbBaY8SUgQUtF75mRRniR0aELEmzTVKGe8
[06/Jun/2020 14:40:26] "GET /oauth2callback?state=VaASAVe2IusAHCsQfc7EfToxNTkxNDM0NTQ3&code=4/0gFCWPMx4qTUrv4wUWpSKbA8Z_rTaZb-YGGDRrK4NsK2UiW6f4MpA_g1Pr5RpyGcRxbCtWlH6qHvKIJvbpG_L9c&scope=https://www.googleapis.com/auth/gmail.readonly HTTP/1.1" 302 0
*****home*****
Internal Server Error: /
Traceback (most recent call last):
  File "D:\PERSONAL DATA\env\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "D:\PERSONAL DATA\env\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "D:\PERSONAL DATA\env\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "D:\PERSONAL DATA\raw_login\google-oauth-mail\gfgauth\views.py", line 23, in home
    credential = storage.get()
  File "D:\PERSONAL DATA\env\lib\site-packages\oauth2client\client.py", line 407, in get
    return self.locked_get()
  File "D:\PERSONAL DATA\env\lib\site-packages\oauth2client\contrib\django_util\storage.py", line 58, in locked_get
    if len(entities) > 0:
  File "D:\PERSONAL DATA\env\lib\site-packages\django\db\models\query.py", line 258, in __len__
    self._fetch_all()
  File "D:\PERSONAL DATA\env\lib\site-packages\django\db\models\query.py", line 1261, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "D:\PERSONAL DATA\env\lib\site-packages\django\db\models\query.py", line 74, in __iter__
    for row in compiler.results_iter(results):
  File "D:\PERSONAL DATA\env\lib\site-packages\django\db\models\sql\compiler.py", line 1096, in apply_converters
    value = converter(value, expression, connection)
TypeError: from_db_value() missing 1 required positional argument: 'context'

SO 帖子之一,建议将context 参数替换为*args, **kwargs。我在源代码中看不到from_db_value 方法。

版本:

django == 3.0.7

python == 3.8

有人可以回答这个问题并提供帮助吗?

我还看到oauth2client 已贬值。是否有任何其他图书馆可以遵循明确的例子?或者任何人都可以发布示例代码吗?

github issue,有人说

您不能将 oauth2client 的存储空间与 google-auth 一起使用。谷歌身份验证 凭证相对简单地持续存在,请参阅: https://github.com/GoogleCloudPlatform/google-auth-library-python-oauthlib/blob/master/google_auth_oauthlib/tool/main.py#L80

但是,作为新手,我无法理解实现这一点。请帮忙!

【问题讨论】:

    标签: python django google-api-python-client oauth2client


    【解决方案1】:

    问题似乎出在oauth2client,不再更新或支持。来自自述文件:

    注意:oauth2client 现已弃用。库中将不再添加任何功能,核心团队正在拒绝支持。我们建议您使用google-authoauthlib。有关弃用的更多详细信息,请参阅 oauth2client 弃用。

    所以我建议你看看这两个包并整合它们。

    这里的要点是,您应该更加小心选择的教程。这个使用 Django 2.0,已经一年多没有支持了。始终寻找与最新版本或最新 LTS 版本相匹配的教程,否则您就是在自找麻烦。

    【讨论】:

    • 谢谢!我已经尝试过这样的教程,但是我不好,找不到有用的链接。如果可能的话,你能分享任何相关的教程/链接吗?
    猜你喜欢
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 2019-10-10
    • 2017-03-27
    • 2019-11-12
    相关资源
    最近更新 更多