Как получить недавно-установленную-версию в рамках сценария Debian postinst?

Если честно, я бы просто разделил комплексное число на два поля с плавающей запятой / десятичное поле и добавил свойство для чтения и записи в виде одного комплексного числа.

Я придумал это настраиваемое поле, которое заканчивается как поле разделения на фактической модели и также вводит вышеупомянутое свойство.

  • contribute_to_class называется глубоко в механизме модели Джанго для всех полей, которые объявлены в модели. Как правило, они могут просто добавить само поле в модель и, возможно, дополнительные методы, такие как get_latest_by_..., но здесь мы угоняем этот механизм, чтобы вместо этого добавить два поля, в которых мы строим, а не само поле «себя» вообще , поскольку он не должен существовать как столбец базы данных. (Это может что-то сломать, кто знает ...) Часть этого механизма объясняется здесь в вики Django.

  • Класс ComplexProperty является дескриптором свойства , который позволяет настраивать то, что происходит, когда свойство, к которому он «присоединен», обращается к экземпляру (осуществляется чтение или запись). (То, как работают дескрипторы, немного выходит за рамки этого ответа, но в документации по Python есть руководство .)

NB: я сделал не проверяйте это за пределами бегущих миграций, так что все может сломаться неожиданным образом, но, по крайней мере, теория обоснована. :)

from django.db import models


class ComplexField(models.Field):
    def __init__(self, **kwargs):
        self.field_class = kwargs.pop('field_class', models.FloatField)
        self.field_kwargs = kwargs.pop('field_kwargs', {})
        super().__init__(**kwargs)

    def contribute_to_class(self, cls, name, private_only=False):
        for field in (
            self.field_class(name=name + '_real', **self.field_kwargs),
            self.field_class(name=name + '_imag', **self.field_kwargs),
        ):
            field.contribute_to_class(cls, field.name)

        setattr(cls, name, ComplexProperty(name))


class ComplexProperty:
    def __init__(self, name):
        self.name = name

    def __get__(self, instance, owner):
        if not instance:
            return self
        real = getattr(instance, self.name + '_real')
        imag = getattr(instance, self.name + '_imag')
        return complex(real, imag)

    def __set__(self, instance, value: complex):
        setattr(instance, self.name + '_real', value.real)
        setattr(instance, self.name + '_imag', value.imag)


class Test(models.Model):
    num1 = ComplexField()
    num2 = ComplexField()
    num3 = ComplexField()


Миграция для этого выглядит как

migrations.CreateModel(
    name="Test",
    fields=[
        (
            "id",
            models.AutoField(
                auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
            ),
        ),
        ("num1_real", models.FloatField()),
        ("num1_imag", models.FloatField()),
        ("num2_real", models.FloatField()),
        ("num2_imag", models.FloatField()),
        ("num3_real", models.FloatField()),
        ("num3_imag", models.FloatField()),
    ],
)

, так что, как вы можете видеть, три ComplexField разбиты на шесть FloatField с. [1119 ]

11
задан 3 April 2009 в 19:23
поделиться