【问题标题】:How do I get Django to treat my float number as a float instead of an int when it renders a query?如何让 Django 在呈现查询时将我的浮点数视为浮点数而不是整数?
【发布时间】:2019-10-29 22:37:53
【问题描述】:

我将 Python 3.7 和 Django 与 PostGres 9.5 一起使用。我有以下 Django 查询

qset = DomainTrackerStat.objects.annotate(
    result=F('num_negative_articles') / (F('num_negative_articles') + F('num_positive_articles'))
).filter(subreddit=subreddit,
         domain=domain,
         num_negative_articles__gt=settings.DOMAIN_NEGATIVE_ARTICLES_THRESHOLD,
         result__gt=settings.DOMAIN_NEGATIVE_ARTICLES_PCT)

常量“settings.DOMAIN_NEGATIVE_ARTICLES_PCT”是“.95”,但是当我的查询被渲染时,SQL 显示为“0”。如果我将其设为“settings.DOMAIN_NEGATIVE_ARTICLES_PCT * 100”,则查询将以“95”作为值呈现,但当然,这不是我想要的值。

如何让 Django 将值解释为浮点数 - 即我想要的正确值?

【问题讨论】:

    标签: python sql django python-3.x postgresql


    【解决方案1】:

    您应该使用ExpressionWrapper [Django-doc],例如:

    from django.db.models import ExpressionWrapper, F, FloatField
    
    DomainTrackerStat.objects.annotate(
        result=ExpressionWrapper(
            F('num_negative_articles') / (F('num_negative_articles') + F('num_positive_articles')),
            output_field=FloatField()
        )
    )

    或者对于 PostgreSql,我们应该在操作数上使用Cast(..) [Django-doc] 运算符:

    from django.db.models import F, FloatField
    from django.db.models.functions import Cast
    
    DomainTrackerStat.objects.annotate(
        result=Cast(F('num_negative_articles'), output_field=FloatField()) /
            Cast(F('num_negative_articles') + F('num_positive_articles'), output_field=FloatField())
    )

    正如文档所说:

    ExpressionWrapper 只是围绕另一个表达式,并提供对其他表达式可能不可用的属性的访问,例如output_fieldExpressionWrapper 在对不同类型的F() 表达式使用算术时是必需的,如Using F() with annotations 中所述。

    【讨论】:

    • 谢谢,您的更改修复了“0”->“.95”问题,但还有另一个问题。当 "F('num_negative_articles') / (F('num_negative_articles') + F('num_positive_articles'))" 被重新定义为 PostGres SQL -- '"myproject_domaintrackerstat"."num_negative_articles" / ("myproject_domaintrackerstat"."num_negative_articles" + "myproject_domaintrackerstat"."num_positive_articles")',表达式被评估为“1”或“0”。它没有被评估为应有的浮点数。
    • @Dave:如果将ExpressionWrapper 应用于其中一个操作数会怎样?这样在除法之前就已经是一个浮点数了。
    • 是的,这就是要走的路。谢谢。附带说明一下,我对 Python 和 Django 框架还很陌生,但是为了获得一个简单的数学表达式,这似乎需要做很多工作。
    • @Dave:问题是如果两个操作数是整数,PostgreSQL 将执行 integer 除法,所以你需要将它们转换为它们的 float i> 同行优先。
    猜你喜欢
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2019-10-17
    • 2013-02-25
    • 1970-01-01
    • 2011-08-13
    • 2021-10-09
    • 1970-01-01
    相关资源
    最近更新 更多