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

hyrbngr7  于 2023-03-04  发布在  Go
关注(0)|答案(7)|浏览(175)

当我试图将UUID属性传递给url参数时,我收到了这个错误。

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

views.py

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

model.py

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

有什么建议吗?

vc9ivgsu

vc9ivgsu1#

Django上有一个关于这个问题的bug标签,但是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)

如果我们做这样的事情

json.dumps(my_object, cls=UUIDEncoder)

应该对uuid字段进行编码。

lvjbypge

lvjbypge2#

将UUID转换为字符串。
uuid_str = str(uuid_item)

dnph8jn4

dnph8jn43#

看起来这个错误与django无关,当使用DjangoJSONEncoder时。不需要编写自己的自定义编码器。由django提供,处理大多数已知的序列化问题。

import json
from django.core.serializers.json import DjangoJSONEncoder
 
json.dumps(my_object, cls=DjangoJSONEncoder)

此处显示详细信息

ca1c2owp

ca1c2owp4#

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

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

FYI -看起来WIM的答案更全面一些。你的正则表达式应该更严格一些。如果你最终使用slug的字符串表示,你会想要一个如下的正则表达式:[A-Za-z0-9\-]+,允许字母数字和连字符。

xmjla07d

xmjla07d5#

我使用转换函数来实现这个,它简单而干净。

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)
eivnm1vs

eivnm1vs6#

我在一个数据库模型中遇到了同样的问题,我想打印出来进行调试,我发现pprint模块中的pprint()函数可以处理这个问题,您也可以给它一个indent参数,以获得与json.dumps()相同的缩进输出
https://docs.python.org/3/library/pprint.html#pprint.pprint
示例:

>>> 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')
ijxebb2r

ijxebb2r7#

另一种方法是使用default=str,我将其留作参考:

import uuid
import json

pk = uuid.UUID("04d8d2dc-e81b-4eaa-8883-d1e361a08da8")
o = json.dumps({"pk": pk}, default=str)
print(o)

输出:

{"pk": "04d8d2dc-e81b-4eaa-8883-d1e361a08da8"}

相关问题