django-shop
django-shop copied to clipboard
field.get_internal_type() result DecimalField
I using generic assign values to django model which contain MoneyField
But when I use get_internal_type()
it do not return MoneyField
I notice we have a migrations
https://github.com/awesto/django-shop/pull/344/commits/6a33d48b86aa7a433b8a13e43745b8742fee66ae
where we remove that overridden method.
I'm not sure is that a mistake or a feature.
So how can we determine a field is a MoneyField in our model.
Right now i'm using field.__class__.__name__ == 'MoneyField'
In the database, amounts are always stored as Decimal types. Reason for this is, that 99% of all shops keep their product prices in one canonical currency and for the remaining 1% is does not make sense to keep the currency side by side with the amount.
Therefore if a shop is to return the product price in different currencies, one shall use the get_price()
method.
That said, model Cart
and Order
keep their sub- and totals in the customers preferred currency. However, even then we keep the _total
as Decimal, whereas property total
returns an amount of type Money in the currency, for which we have another field.
For the record, I made bad experiences with systems that store prices without currencies. IMHO, the correct way is to always store the currency along with the decimal value. For example:
amount (Decimal) | currency (String) |
---|---|
10.0 | EUR |
I am ok with django-shop doing it differently as long as I have a good way to override it and hook in my own behaviour, but I would really prefer to store the currency along with the price.
In that case I would create my own MoneyField, which on the DB-layer is composed of two fields: the amount and the currency. But as said, in 99% of all shops, that additional database column will always contain only one currency.
@jrief I agree.
@AndyHoang please provide a reproducible use-case (code / traceback).
I have function to get all none reference field ob a model
def get_none_reference_field(cls_model):
return [f for f in cls_model._meta.get_fields() if (not(f.many_to_one or f.related_model))]
a function to assign value by field.name
def assign_value_by_type(self, field, value):
try:
if field.get_internal_type() == 'DateTimeField':
value = self.parse_time(value)
elif field.get_internal_type() == 'IntegerField':
value = int(value)
elif field.get_internal_type() == 'DecimalField':
if field.__class__.__name__ == 'MoneyField':
splits = value.split()
value = Money(splits[0], splits[1])
elif field.get_internal_type() == 'FloatField':
if field.__class__.__name__ == 'MeasurementField':
cls = field.measurement
splits = value.split()
value = cls(**{splits[1]: splits[0]})
elif field.get_internal_type() == 'ArrayField':
if isinstance(value, str):
to_remove = "\"\'"
for char in to_remove:
value = value.replace(char, "")
value = map(lambda v: v.strip(), value.split(','))
setattr(self, field.name, value)
and have dict with key value that have the same key with model (not using serializer) So that my use case. So basically I would like to check that field like MeasurementField, DateTimeField... (right now it my work around) Am I provide enough info? I'm also new to python, if you have any suggestion, i'm really appreciated