【问题标题】:Google API storage returns string, not credentials objectGoogle API 存储返回字符串,而不是凭据对象
【发布时间】:2015-05-30 00:28:27
【问题描述】:

我正在尝试将 google-api 用于 python。 我已经设法将凭据存储在 CredentialsField(基本上是复制 this)实现中。

我可以得到一个存储对象:

>>> storage = Storage(CredentialsModel, 'id', user, 'credential')   
>>> storage
<oauth2client.django_orm.Storage object at 0x7f1f8f1260f0>

没问题。但是当我尝试获取凭据对象时:

>>> credential = storage.get()
>>> credential

我只得到一个大字符串(7482 个字符)而不是凭据对象。是什么赋予了? (我认为字符串可能是一个字节数组,因为它以'\\x67414e6a6 开头。

我也在使用 Python 3。

关于为什么我得到一个字符串而不是 Credentials 对象有什么想法吗?

【问题讨论】:

  • 我认为它与凭证对象有关。它在凭证参考中有一些随机值。尝试在凭证类中包含一些 getter 和 setter,这将帮助您打印凭证类。

标签: python django google-api gmail-api


【解决方案1】:

如果您仍然需要,我实际上已经找到了答案:

问题在于 django_orm 中的 CredentialFields 类定义了一个 metaclass 变量,python3 不再支持该变量。

因此,有必要把它改成这样:

类 CredentialsField(models.Field, metaclass=models.SubfieldBase):

有人在 github 存储库中打开了一个问题:

https://github.com/google/oauth2client/issues/168

【讨论】:

    【解决方案2】:

    我的python3、django 1.8和postgres数据库的解决方案:

    在将字节数据保存到数据库之前和从数据库检索数据之后缺少一个步骤:字节数据需要先转换为字符串。您可以使用decode("utf-8")encode("utf-8") 将字节转换为字符串,反之亦然。

    您也不需要__metaclass__,但需要有get_prep_value()from_db_value() 函数。 整个类CredentialsField 应该这样重写:

    class CredentialsField(models.Field):
        def __init__(self, *args, **kwargs):
            if 'null' not in kwargs:
                kwargs['null'] = True
            super().__init__(*args, **kwargs)
    
        def get_internal_type(self):
            return "TextField"
    
        def to_python(self, value):
            if value is None:
                return None
            if isinstance(value, oauth2client.client.Credentials):
                return value
    
            value = value.encode("utf-8")  # string to byte
    
            return pickle.loads(base64.b64decode(value))
    
        def from_db_value(self, value, expression, connection, context):
            return self.to_python(value)
    
        def get_db_prep_value(self, value, connection, prepared=False):
            if value is None:
                return None
    
            byte_repr = base64.b64encode(pickle.dumps(value))
    
            return byte_repr.decode("utf-8")  # byte to string
    
        def get_prep_value(self, value):
            return self.get_db_prep_value(value)
    

    【讨论】:

      猜你喜欢
      • 2017-07-18
      • 2011-07-29
      • 2012-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多