Python UUID('...') 不是 JSON 可序列化的

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36588126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 18:03:50  来源:igfitidea点击:

UUID('...') is not JSON serializable

pythondjangouuid

提问by DJeanCar

I get this error when i try to pass the UUID attribute to url parameter.

当我尝试将 UUID 属性传递给 url 参数时出现此错误。

urlpatterns = [
    url(r'^historia-clinica/(?P<uuid>[W\d\-]+)/$', ClinicHistoryDetail.as_view(), name='...'),
]

views.py

视图.py

class ClinicHistoryDetail(...):
     ...
     my_object = MyModel.objects.create(...)
     ...
     return redirect(reverse('namespace:name', kwargs={'uuid' : my_object.id}))

model.py

模型.py

class MyModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    ...

Any suggestions?

有什么建议?

回答by IVI

There is a bug ticket on Django regarding this issue however a custom so called 'complex encoder' by python docs can help you.

Django 上有一个关于这个问题的错误票,但是 python 文档中所谓的“复杂编码器”可以帮助你。

import json
from uuid import UUID


class UUIDEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, UUID):
            # if the obj is uuid, we simply return the value of uuid
            return obj.hex
        return json.JSONEncoder.default(self, obj)

Now if we did something like this

现在如果我们做这样的事情

json.dumps(my_object, cls=UUIDEncoder)

Your uuid field should be encoded.

您的 uuid 字段应该被编码。

回答by Jordan Haines

For using the UUID in a URL like that, you should pass it as a string:

要在这样的 URL 中使用 UUID,您应该将其作为字符串传递:

 return redirect(reverse('namespace:name', kwargs={'uuid' : str(object.id)}))

FYI - it looks like WIMs answer is a bit more thorough. Your regex should certainly be tightened up. If you end up using the string representation of the slug, you'll want a regex like this: [A-Za-z0-9\-]+which allows for alphanumerics and hyphens.

仅供参考 - 看起来 WIM 的回答更彻底一些。您的正则表达式当然应该收紧。如果您最终使用 slug 的字符串表示形式,您将需要这样的正则表达式:[A-Za-z0-9\-]+它允许使用字母数字和连字符。

回答by Maoz Zadok

I use convert function for this, it is simple and clean.

我为此使用了转换功能,它既简单又干净。

import json
from uuid import UUID
def uuid_convert(o):
        if isinstance(o, UUID):
            return o.hex

json.dumps(users,indent=4,default=uuid_convert)

回答by user5359531

I had this same problem with a UUID field in a database model that I wanted to print out for debugging. I found that the pprint()function from the pprintmodule can handle this. You can also give it an indentargument to get the same kind of indented output that you would get from json.dumps()

我想打印出来用于调试的数据库模型中的 UUID 字段也有同样的问题。我发现模块中的pprint()函数pprint可以处理这个问题。您还可以给它一个indent参数以获得与您将获得的相同类型的缩进输出json.dumps()

https://docs.python.org/3/library/pprint.html#pprint.pprint

https://docs.python.org/3/library/pprint.html#pprint.pprint

Example:

例子:

>>> import uuid
>>> import pprint
>>> import json
>>> x = uuid.UUID('12345678123456781234567812345678')
>>> x
UUID('12345678-1234-5678-1234-567812345678')
>>> print(x)
12345678-1234-5678-1234-567812345678
>>> json.dumps(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
...
...
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: UUID('12345678-1234-5678-1234-567812345678') is not JSON serializable
>>> pprint.pprint(x)
UUID('12345678-1234-5678-1234-567812345678')