【问题标题】:Number order ignores decimals in Django Postgres数字顺序忽略 Django Postgres 中的小数
【发布时间】:2016-05-16 18:01:41
【问题描述】:

在 SQLite 中本地构建。我的应用程序有对象价格的数字。在 SQLite 中,我能够定期对价格进行排序(例如:914 美元、799 美元、120 美元、95 美元、9.00、7.50 美元。)

将应用程序推送到 Postgres 后,数字如下: 95、914、9.00、799、7.50、120。

我显然希望在 Postgres 中按价格从高到低和从低到高来订购它们。我究竟做错了什么?

模型字段:

price = models.DecimalField(max_digits=8, decimal_places=2, null=True)

网址:

url(r'^browse/price_desc/$', 'collection.views.price_desc', name="pricehigh")

查看:

def price_desc(request):
       items = item.objects.all.order_by('-price')

       return render(request, 'index.html', {
            'items' : items,
})

【问题讨论】:

  • 如果他按照他的建议订购了 95、914、9.00、799、7.50、120 的商品,那么显然订购是错误的。

标签: python django postgresql sqlite


【解决方案1】:

首先,decimalField 基于 python decimal

根据this answer 关于十进制值的问题,postgres 存储小数的方式是通过压缩的 BCD 字符串。您的订单显示方式反映了排序字符串的顺序,而不是数字。

不太清楚 django 如何实现对 DecimalField 的排序,但我假设它像对字符串一样对它进行排序。

虽然 DecimalField 似乎适合您的用例,但您可能希望切换到 FloatField 以获得所需的排序。

【讨论】:

  • 在处理货币时建议使用浮点数进行存储感觉是个坏主意。
【解决方案2】:

Postgres 存储和订购 NUMERIC 值,如您所料:

CREATE TABLE numeric_test (id SERIAL, value NUMERIC(8,2));
INSERT INTO numeric_test (value) VALUES (914), (799), (120), (95), (9), ('7.5');
SELECT * FROM numeric_test;
 id │ value  
────┼────────
  1 │ 914.00
  2 │ 799.00
  3 │ 120.00
  4 │  95.00
  5 │   9.00
  6 │   7.50
(6 rows)

我怀疑您的数据库没有存储为NUMERIC。也许您的迁移实际上是将列创建为TEXT

【讨论】:

  • 我认为问题出在这些方面。当我第一次在本地制作模型时,十进制字段是一个字符字段。不确定这是否与它有关。我显然是数据库新手,那么您建议我从哪里开始进行故障排除?
  • 你能展示你的迁移文件吗?很可能它仍然被创建为VARCHAR 或其他。 可能可以迁移和修复,但如果您仍处于早期阶段,删除此应用的所有迁移并重新开始可能会更简单。
  • 我刚刚检查了 postgres 数据库,模型确实有一个 CharField。您是否建议删除生产服务器上的迁移?
  • 可能能够手动迁移:如果您的迁移在正常运行时创建了正确的表结构,并且所有迁移都已应用,那么您可能不想删除迁移并再次运行。
猜你喜欢
  • 2022-01-25
  • 2010-12-03
  • 2020-02-18
  • 1970-01-01
  • 2015-05-13
  • 1970-01-01
  • 2020-03-11
  • 1970-01-01
相关资源
最近更新 更多