Я использую Google App Engine (python) и Jinja2, и я хотел бы воспользоваться функцией webapp2 для интернационализации и локализации валюты, то есть хранить цены в виде числа и производить правильное форматирование, используя встроенный метод webapp2 i18n. Тогда сначала у меня должен быть правильный тип данных для моих цен.
Я перехожу из прототипа, который использовал String для цен, к более реальной реализации, где я использую некоторый числовой тип данных для цен + другую переменную, в какой валюте это происходит. Поэтому в процессе миграции я буду использовать обе переменные, перенести на использование чисел вместо строк, удалить строковый тип данных и выполнить задание mapreduce для обновления старых объектов на числовую переменную, такую как целое или десятичное, вместо того, чтобы разрешать текст / строка для представления цены.
Моя среда (механизм приложений Google) не поддерживает десятичный тип данных, и я мог бы также использовать целые числа только потому, что он покупает и продает более изнурительные статьи и объекты, такие как дома, автомобили и т. Д., Где доллары имеют значение и центы обычно указываются только как 00. Таким образом, я отказался от реализации свойства десятичного числа, и в любом случае это было ошибкой, и теперь я спрашиваю, какой правильный способ установить цену, и если я должен разыграть ее перед сохранением?
Т.е.. это правильно:
form = EntityForm(self.request.params)
if form.validate():
entity.title = form.title.data
entity.name = form.name.data
entity.email = form.email.data
entity.text = form.text.data
entity.set_password(form.password.data)
entity.price = form.price.data
try:
if form.price.data:
form.price.data=form.price.data.replace(',','.').replace(' ', '')
entity.integer_price = int(form.price.data)
except:
pass
Или мне не нужно приводить переменную к целому числу, и преобразование типов будет осуществляться за кулисами? Я считаю, что переменные формы - это строки, а цена должна быть числом, чтобы сортировать и фильтровать правильно.
Когда я использовал собственное десятичное свойство, я начал получать эту ошибку:
Traceback (most recent call last):
File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 545, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/s~montaoproject/validation.355292363398040911/i18n.py", line 653, in get
ads = paginator.page(page)
File "/base/data/home/apps/s~montaoproject/validation.355292363398040911/paginator.py", line 42, in page
return Page(self.object_list[bottom:top], number, self)
File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 2189, in __getitem__
return self.fetch(limit, start)
File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 2084, in fetch
return list(self.run(limit=limit, offset=offset, **kwargs))
File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 2237, in next
return self.__model_class.from_entity(self.__iterator.next())
File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/search/__init__.py", line 463, in from_entity
return super(SearchableModel, cls).from_entity(entity)
File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1411, in from_entity
entity_values = cls._load_entity_values(entity)
File "/base/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1387, in _load_entity_values
value = prop.make_value_from_datastore(entity[prop.name])
File "/base/data/home/apps/s~montaoproject/validation.355292363398040911/main.py", line 98, in make_value_from_datastore
return decimal.Decimal(value)
File "/base/python27_runtime/python27_dist/lib/python2.7/decimal.py", line 548, in __new__
"Invalid literal for Decimal: %r" % value)
File "/base/python27_runtime/python27_dist/lib/python2.7/decimal.py", line 3844, in _raise_error
raise error(explanation)
InvalidOperation: Invalid literal for Decimal: u''
Код, который я использовал, был:
class DecimalProperty(db.Property):
data_type = decimal.Decimal
def get_value_for_datastore(self, model_instance):
return str(super(DecimalProperty, self).get_value_for_datastore(model_instance))
def make_value_from_datastore(self, value):
return decimal.Decimal(value)
def validate(self, value):
value = super(DecimalProperty, self).validate(value)
if value is None or isinstance(value, decimal.Decimal):
return value
elif isinstance(value, basestring):
return decimal.Decimal(value)
raise db.BadValueError("Property %s must be a Decimal or string." % self.name)
Но это не сработало для меня, я начал получать слово «None» в виде строки для статей / объектов, которые не имели цены, из-за которой мое приложение не загружалось должным образом, поэтому я полностью удалил попытку десятичной дроби, и я собираюсь для решения с целочисленным свойством вместо этого и подтвердите, что входные данные либо пустые, либо целое число, которое я могу сделать с помощью wtforms.
Таким образом, я больше не использую пользовательское десятичное число, и мы решили, что integerproperty подойдет, и наихудший случай, если потребуется дробная часть валюты, тогда можно использовать другую переменную "центы", чтобы я использовал целые числа для долларов и целые числа для центов и последний редко или никогда не используется.
Итак, решение, которое я планирую сейчас, простое:
Статья класса (GeoModel, search.SearchableModel):
integer_price = IntegerProperty() #store dollars as dollars
currency = db.StringProperty(choices=(
'EUR',
'ARS',
'AUD',
'BRL',
'GBP',
'CAD',
'CZK',
'DKK',
'HKD',
'HUF',
'ILS',
'INR',
'JPY',
'MXN',
'NZD',
'NOK',
'PLN',
'PHP',
'SGD',
'SEK',
'SGD',
'CHF',
'USD',
'THB',
'TWB',
), verbose_name='Currency')
price = db.StringProperty(verbose_name='price') #quit using this and use a number instead
Знаете ли вы, если я действительно должен сделать преобразование типа или любую другую ловушку, в которую я могу попасть? Согласны ли вы с тем, что мне не нужны десятичные дроби для моего случая использования (реклама автомобиля, реклама дома) и т. Д., Хотя это возможно при более экзотических ценах, которые я должен запретить, например. «20 долларов за галлон» - это цена, с которой я не могу справиться, но вместо этого ее можно указать в тексте, поскольку это особый тип цены (за единицу объема), а также, если цена указана в центах. Хранение цены в виде целочисленного свойства позволит значительно улучшить форматирование цен, тем более что мое приложение интернационализировано и локализовано.
Спасибо за любой ответ или комментарий