Search code examples
djangodjango-modelsserializationdjango-rest-frameworkdjango-serializer

Django dumpdata serializing an int as string


I've been trying to make a custom class/type, defined in a separate db.py file, to be properly serialized as an int when doing a manage.py dumpdata command, but this BitFlagField always ends up exported as a string, the value accompanied by double quotes, while other integer fields are properly exported without the quotes in the JSON file. The person that made it left the place almost a year ago, so I can't get any help from him.

This is the class' code - note that I've fixed the __str__ function and also changed the __repr__ to return repr(self.value)

This is how it looks after the dumpdata: (...), "blocked": "8"}} ; For comparison, two other integer fields don't come with the value enclosed by quotes: "pk": 1, "bit":8,. Because of this, manage.py loaddata fails:

django.core.serializers.base.DeserializationError: Problem installing fixture '/home/abcd/djangoapp/data.json': '>=' not supported between instances of 'str' and 'int': (core.userextra:pk=1) field_value was '8'

If I manually remove the quotes from the "blocked" field's value, the loaddata command works.

If I delete both __str__ and __repr__ functions, the object type is what ends up as the data: (...), "blocked": "<core.db.BitFlag object at 0x7f9f2eb0bf40>"}}. If I make either of them return self.value, it complains that it was expecting a str type.

What I need is to either save that value as an int in the JSON, which so far I haven't managed to, or deserialize it somewhere, but I can't figure out the where part, as, in my mind, that should be a simple return int(self.value).


Solution

  • After talking to a variety of coworkers, one of them found the issue. The BitFlagField class needed the following function

    def value_to_string(self, obj):
        value = self.value_from_object(obj)
        return self.get_prep_value(value)
    

    Adding it made the dumpdata work as intended, with the field being exported as an int.

    "It was in the docs all along" - True and I'm not sure how I missed this.