【问题标题】:Custom Django count filtering自定义 Django 计数过滤
【发布时间】:2016-01-23 13:40:44
【问题描述】:

会显示很多网站:

  • “1.8K 页”而不是“1,830 页”

  • “43.2M 页”而不是“43,200,123 页”

有没有办法在 Django 中做到这一点?

例如,以下代码将生成查询集中的量化对象数量(即 3,123):

Books.objects.all().count()

有没有办法添加自定义计数过滤器以返回“3.1K 页”而不是“3,123 页?

提前谢谢你!

【问题讨论】:

  • 您是否希望更改实际查询集返回的内容?或者只是在您的页面上显示?它们是两种完全不同的东西。
  • 我会查看intword 内置过滤器。它并不能完全满足您的要求,因为它使低于一百万的数字保持不变并使用完整的单词而不是 KM 等,但这将是自定义过滤器的一个很好的起点. github.com/django/django/blob/master/django/contrib/humanize/…
  • @electrometro 哪个更容易实现?我假设更改查询集的响应将是更好的长期目标,但现在简单地显示它就可以了。

标签: django django-models django-views django-filter


【解决方案1】:

首先,我不会做任何改变 Django 的 ORM 部分工作方式的事情。如果您只打算在一个地方使用它,可以在两个地方完成 - 在前端进行。话虽如此,有很多方法可以实现这一结果。只是为了表达一些想法,您可以在模型上编写一个调用 count 的属性,然后将其转换为后端更易于阅读的东西。如果您想在前端执行此操作,您可能需要找到一个可以进行转换的 JavaScript 库。

稍后我将在我的计算机上对其进行编辑并添加该属性的示例。

编辑:回答您的评论,更容易实现取决于您在 python 和 JavaScript 方面的技能。我更喜欢 python,所以我可能会在模型的某个地方做它。

Edit2:我写了一个示例,向您展示如何在基本模型或您需要这些数字的模型上执行classmethod。我找到了一个名为humanize 的python 包,我利用它的函数将这些转换为可读的,并对其进行了一些修改以允许数千并取出一些超大数转换。

def readable_number(value, short=False):
    # Modified from the package `humanize` on pypy.
    powers = [10 ** x for x in (3, 6, 9, 12, 15, 18)]
    human_powers = ('thousand', 'million', 'billion', 'trillion', 'quadrillion')
    human_powers_short = ('K', 'M', 'B', 'T', 'QD')
    try:
        value = int(value)
    except (TypeError, ValueError):
        return value

    if value < powers[0]:
        return str(value)
    for ordinal, power in enumerate(powers[1:], 1):
        if value < power:
            chopped = value / float(powers[ordinal - 1])
            chopped = format(chopped, '.1f')
            if not short:
                return '{} {}'.format(chopped, human_powers[ordinal - 1])
            return '{}{}'.format(chopped, human_powers_short[ordinal - 1])


class MyModel(models.Model):
    @classmethod
    def readable_count(cls, short=True):
        count = cls.objects.all().count()
        return readable_number(count, short=short)


print(readable_number(62220, True))  # Returns '62.2K'
print(readable_number(6555500))  # Returns '6.6 million'

我会将readable_number 粘贴在某种实用程序中,然后将其导入您的模型文件中。一旦你有了它,你就可以把那个字符串粘在你想要的前端的任何地方。

您将使用MyModel.readable_count() 来获取该值。如果你想在MyModel.objects.readable_count() 下使用它,你需要为你的模型创建一个自定义对象管理器,但这有点高级。

【讨论】:

    猜你喜欢
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 2011-08-06
    • 1970-01-01
    相关资源
    最近更新 更多