Last active
July 26, 2022 23:36
-
-
Save tubaman/b38e63ede79b4aecfae136ee60bc4a5b to your computer and use it in GitHub Desktop.
DecimalField workaround for SQLite's lack of a real fixed-point field
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
from decimal import Decimal | |
from django import db | |
from django.db.models import DecimalField as DjangoDecimalField | |
logger = logging.getLogger(__name__) | |
#logger.setLevel(logging.DEBUG) | |
class DecimalField(DjangoDecimalField): | |
"""On SQLite, store as an integer. On all other backends, use DecimalField""" | |
def get_internal_type(self): | |
if db.connection.vendor == 'sqlite': | |
return "IntegerField" | |
else: | |
return "DecimalField" | |
def get_db_prep_save(self, value, connection): | |
if connection.vendor == 'sqlite': | |
logger.debug("value: %r, connection: %r", value, connection) | |
result = int(value * 10**self.decimal_places) | |
logger.debug("result: %r", result) | |
return result | |
else: | |
return super().get_db_prep_save(value, connection) | |
def from_db_value(self, value, expression, connection): | |
if connection.vendor == 'sqlite': | |
logger.debug("value: %r, expression: %r, connection: %r", value, expression, connection) | |
result = Decimal(value) / 10**self.decimal_places | |
logger.debug("result: %r", result) | |
return result | |
else: | |
return super().from_db_value(value, expression, connection) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment