【问题标题】:Handling numbers that are prices with GAE + WTForms使用 GAE + WTForms 处理价格数字
【发布时间】:2011-12-12 03:19:53
【问题描述】:

我使用 Google 应用引擎 (python) 和 Jinja2,我想利用 webapp2 的货币国际化和本地化功能,即将价格存储为数字,并使用 webapp2 的内置 i18n 方法进行正确的格式设置。那么首先我必须有正确的数据类型来匹配我的价格。

我正在从一个使用字符串作为价格的原型迁移到一个更真实的实现,其中我使用一些数字数据类型作为价格+另一个变量是哪种货币。因此,在迁移期间,我将同时使用这两个变量,迁移到使用数字而不是字符串,删除字符串数据类型并进行 mapreduce 作业以将旧实体更新为基于数字的变量,例如整数或小数,而不是允许文本/代表价格的字符串。

我的环境(谷歌应用程序引擎)不支持十进制数据类型,我不妨只使用整数,因为使用的是购买和销售更昂贵的物品和物品,如房屋、汽车等。美分通常只列为 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”作为没有定价的文章/对象的字符串,这使我的应用程序无法正确加载,因此我完全删除了小数点尝试,我要走了对于使用 integerproperty 的解决方案,并验证输入是空的还是整数,我可以使用 wtforms 执行此操作。

所以我不再使用自定义小数,我们决定使用整数属性,最坏的情况是,如果需要货币的分数,那么 a 可以使用另一个变量“美分”,以便我使用整数表示美元,整数表示美分后者很少或从未使用过。

所以我现在计划的解决方案很简单:

类文章(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 美元”是我无法处理的价格,但可以在文本中指定,因为它是一种特殊类型的价格(每单位体积),如果价格以美分为单位,同样如此。将价格存储为整数属性将允许更好地格式化价格,特别是因为我的应用程序是国际化和本地化的。

感谢您的任何回答或评论

【问题讨论】:

  • 如果你想使用decimal,你可以将它包含在你的代码中,只需将你的十进制对象更改为str。如果您在本机环境中有十进制,当您导入它时,decimal.__file__ 的路径将包含原始源(或编译源)。您可以将其复制到您的应用程序引擎目录。 (我试图在网上找到十进制的来源)。

标签: python google-app-engine internationalization jinja2 money-format


【解决方案1】:

请查看问题编号6595this。如果您的问题出在该区域,则可以通过补丁解决,否则我建议在 except 块中捕获该区域并转储变量,尤其是单个序数,以确保传递给 Decimal 的内容是合法的可接受字符.对我来说,它抱怨的字符是一个空字符串看起来有点奇怪,所以让我们尝试确认所有字符都是有效的,因为我们在这里处理的是 unicode。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多