coddingtonbear / django-measurement

Easily store, retrieve, and convert measurements of weight, volume, distance, area and more.
MIT License
145 stars 32 forks source link

Serialization of Validators does not work #88

Closed akramhussein closed 4 years ago

akramhussein commented 5 years ago

When I use the code examples from the unit tests that use MinValueValidator and MaxValueValidator, such as:

    measurement_weight = MeasurementField(
        measurement=measures.Weight,
        validators=[
            MinValueValidator(measures.Weight(kg=1.0)),
            MaxValueValidator(measures.Weight(kg=3.0))
        ],
        blank=True, null=True,
    )

From here.

Upon creating the migration I receive the error:

  File "manage.py", line 29, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 353, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/makemigrations.py", line 184, in handle
    self.write_migration_files(changes)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/makemigrations.py", line 222, in write_migration_files
    migration_string = writer.as_string()
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/writer.py", line 151, in as_string
    operation_string, operation_imports = OperationWriter(operation).serialize()
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/writer.py", line 110, in serialize
    _write(arg_name, arg_value)
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/writer.py", line 62, in _write
    arg_string, arg_imports = MigrationWriter.serialize(item)
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/writer.py", line 279, in serialize
    return serializer_factory(value).serialize()
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/serializer.py", line 37, in serialize
    item_string, item_imports = serializer_factory(item).serialize()
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/serializer.py", line 197, in serialize
    return self.serialize_deconstructed(path, args, kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/serializer.py", line 85, in serialize_deconstructed
    arg_string, arg_imports = serializer_factory(arg).serialize()
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/serializer.py", line 37, in serialize
    item_string, item_imports = serializer_factory(item).serialize()
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/serializer.py", line 102, in serialize
    return self.serialize_deconstructed(*self.value.deconstruct())
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/serializer.py", line 81, in serialize_deconstructed
    arg_string, arg_imports = serializer_factory(arg).serialize()
  File "/usr/local/lib/python3.7/site-packages/django/db/migrations/serializer.py", line 353, in serializer_factory
    "topics/migrations/#migration-serializing" % (value, get_docs_version())
ValueError: Cannot serialize: Mass(kg=1.0)
There are some values Django cannot serialize into migration files.
For more, see https://docs.djangoproject.com/en/2.1/topics/migrations/#migration-serializing

Using Django version 2.1.7

codingjoe commented 5 years ago

Hi @akramhussein thanks for reaching out. You are correct that is an issue in python-measurement. Django requires values in migrations to be "serializable", which means they need to implement a method called deconstruct as well as __eq__.

I would very much welcome a fix for that, would you be up to create a pull-request over here https://github.com/coddingtonbear/django-measurement and add the deconstruct method?

Best -Joe

akramhussein commented 5 years ago

Hi @codingjoe - happy to tackle this PR. Can't do it immediately, but will hopefully end of this week, start of next.

codingjoe commented 5 years ago

@akramhussein sure, just ping me, when you are done

rajnishdahiya commented 4 years ago

Not sure what's the status here. But it still doesn't work out of the box. But there is an easy fix

@deconstructible
class Distance(measures.Distance):
  pass

@deconstructible
class Weight(measures.Weight):
  pass
codingjoe commented 4 years ago

@rajnishdahiya good point. I will try to fix that in the next version.