Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django model serialization problem with default fields

Inside of my app model, I use IntegerRangeField fields:

from django.db import models
from django.contrib.postgres.fields import IntegerRangeField
from django.contrib.postgres.validators import RangeMinValueValidator, RangeMaxValueValidator
from psycopg2.extras import NumericRange


class MyModel(models.Model):
    ...

    field = IntegerRangeField(default=NumericRange(400, 600), validators=[
        RangeMinValueValidator(1),
        RangeMaxValueValidator(1000)
    ])
    ...

The "default" attributes are used in the admin panel UI only, and are not needed anywhere else.

If I add them after migration, they work smoothly. However, if I add them before I run makemigrations, I get this message:

ValueError: Cannot serialize: NumericRange(400, 600, '[)') There are some values Django cannot serialize into migration files.

I don't even want the default values to be saved to my PostgreSQL database, I just want to not have to remove and bring them back every time I run makemigrations.

Any ideas?

(Didn't work: a custom object with "lower" and "higher" attributes, a single integer, a string, a tuple)

Python: 3.6.6, Django: 2.1.2, PostgreSQL: 11.0

like image 403
ozz Avatar asked Jun 13 '26 20:06

ozz


1 Answers

EDIT I should point out that the original question was 2 years old, but at least in django 3.1, their is a serializer that you must register separately.

You need to register the serializer that is provided by django.

from psycopg2.extras import NumericRange
from django.contrib.postgres.serializers import RangeSerializer
from django.db.migrations.writer import MigrationWriter

MigrationWriter.register_serializer(NumericRange, RangeSerializer)

This piece was not in the documentation, but then you can add your defaults as you'd expect:

class AgeDivision(models.Model):
    name = models.CharField(max_length=50, unique=True)
    age_range = fields.IntegerRangeField(
        unique=True, blank=True, default=NumericRange(None, None))

as for where to put this, it just needs to go along side any module that is only loaded once. The documentation didn't specify where to put custom serializers (as least that I could find), but I'd say put them in the migrations/__init__.py file for any app that requires the serializer. here's the documentation on migration serialization: https://docs.djangoproject.com/en/3.1/topics/migrations/#custom-serializers

like image 114
thomasrea0113 Avatar answered Jun 16 '26 10:06

thomasrea0113