Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

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

Any suggestions?

like image 890
DJeanCar Avatar asked Apr 13 '16 03:04

DJeanCar


5 Answers

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

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.

like image 200
IVI Avatar answered Nov 04 '22 02:11

IVI


Convert UUID to str.

uuid_str = str(uuid_item)

like image 29
Henshal B Avatar answered Nov 04 '22 02:11

Henshal B


Looks like this error is no more relevant for django, while using DjangoJSONEncoder. No need to write own custom encoder. Provided by django handles most known serializing problems.

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

Details here

like image 6
Geolimber Avatar answered Nov 04 '22 03:11

Geolimber


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

 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.

like image 5
Jordan Haines Avatar answered Nov 04 '22 02:11

Jordan Haines


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)
like image 4
Maoz Zadok Avatar answered Nov 04 '22 03:11

Maoz Zadok