Django - Аннотируйте и приведите зашифрованный TextField к FloatField на 2 десятичных знака - PullRequest
0 голосов
/ 19 сентября 2018

Я использую Поля Django pgcrypto , чтобы зашифровать значение суммы в модели Invoice следующим образом:

from pgcrypto import fields

class Invoice(models.Model):
    # Some other fields
    amount_usd = fields.TextPGPSymmetricKeyField(default='')

    objects = InvoicePGPManager()  # Manager used for PGP Fields

Я использую TextPGPSymmetricKeyField, потому что я 've, чтобы хранить значение как число с плавающей точкой, и django-pgcrypto-fields не имеет эквивалента для FloatField.

Теперь мне нужно передать это значение amount_usd через API, и я должен ограничить десятичные дроби до двух мест.

Я пытался использовать следующее:

Invoice.objects.all().values('amount_usd').annotate(
    amount_to_float=Cast('amount_usd', FloatField())
)

Но это выдает ошибку, поскольку байты (зашифрованные данные) не могут быть преобразованы в число с плавающей точкой.

Я пытался использоватьэто также:

from django.db.models import Func

class Round(Func):
    function = 'ROUND'
    template='%(function)s(%(expressions)s, 2)'


Invoice.objects.all().annotate(PGPSymmetricKeyAggregate(
            'amount_usd')).annotate(amount=Cast(
            'amount_usd__decrypted', FloatField())).annotate(
            amount_final = Round('amount'))

Я получаю следующую ошибку:

django.db.utils.ProgrammingError: function round(double precision, integer) does not exist
LINE 1: ...sd, 'ultrasecret')::double precision AS "amount", ROUND(pgp_...
                                                         ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

Можно ли преобразовать зашифрованное поле в FloatField с точностью до 2 десятичных знаков?

1 Ответ

0 голосов
/ 19 сентября 2018

Ваша ошибка говорит: double precision AS "amount" Это потому, что вы конвертируете amount_usd в FloatField, который преобразуется в SQL с двойной точностью.

Попробуйте использовать DecimalField (конвертирует в числовой типв SQL) с его аргументами.

Invoices.objects.all().annotate(amount=Cast(
    PGPSymmetricKeyAggregate('amount_usd'),
    DecimalField(max_digits=20, decimal_places=2)))

Проверьте документацию здесь: Django DecimalField

...