2017-03-17 10 views
0

cb、66.45という名前のGETパラメータを解析し、floatに変換して66.45を得ました。djangoは間違った数字を使ってデータを照会します

cb = request.GET.get("cb", '') 
if re.match('^\d+(\.\d+)?$', cb): 
    cb=float(cb) 
    params['cb'] = cb 

次に、dbデータのクエリに使用しました。空の状態です。実際に

products = Product.objects.filter(**params) 

、私はデバッグ時に、クエリのSQLは66.4500000000000028421709430404007434844970703125代わりの66.45を使用し、それは私の空のクエリ結果を引き起こしました。

cbは、以下のように製品モデルで定義されています

cb = models.DecimalField(max_digits=6, decimal_places=2, default=0) 

は何も悪いことはありますか?私は混乱しています。

+0

フロートは正確なタイプではありません。したがって、クエリを実行する前にcbを66.45に調整する必要があります。 – Guinner

+0

浮動小数点型変換を行わずに 'cb'を使ってみましたか?つまり、文字列として使用しましたか? –

+0

これは、mysqlがサポートしているため、cbが文字列として使用されているときに機能します。 私は、Pythonインタプリタでfloatにcbをキャストしようとしましたが、同じ66.45を持っています。なぜdjangoクエリーで使用すると正確ではないのですか?そして、数字を投げるのはとても危険ですか? – Uphie

答えて

0

@nik_mと@Renyuan wangに感謝します。これは、cbが文字列またはcb=Decimal(cb)として使用されている場合に機能します。

私はまだ混乱しています。

enter image description here

私は、Djangoはおそらく、この問題が発生するが、私はわからないと思います。

+0

あなたは 'print'を信じてはいけません。 floatを使った 'print'のデフォルトのフォーマットがあると思います。 'print( '%3.15f'%cb)'を試してみると、66.450000000000003となるでしょう。 –

+0

はい、そうです。 Djangoは最も正確なcbの値を使います。 66を投げ、66.000 ... 000、66.4が66.400 ... 40625を得ました。 キャスティングでは66.4や45.43などの正確な値は期待できず、66と45.5などの正確な値が必要な場合もあります。 フロートキャストを慎重に使用する必要があります。 – Uphie

関連する問題