2

Djangoに関する別の質問があります。

私はこのコードを持っています:

views.py

cursor = connections['cdr'].cursor()
calls = cursor.execute("SELECT * FROM cdr where calldate > '%s'" %(start_date))
result = [SQLRow(cursor, r) for r in cursor.fetchall()]
return render_to_response("cdr_user.html",
    {'calls':result }, context_instance=RequestContext(request))

データベースはdjangoプロジェクトの一部ではないため、このようなMySQLクエリを使用します。

私のcdrテーブルにはdurationというフィールドがあり、それを60で割り、その結果に0.16のような浮動小数点数を掛ける必要があります。

テンプレートタグを使用してこの値を乗算する方法はありますか?そうでない場合、私の見解でそれを行うための良い方法はありますか?

私のテンプレートは次のようなものです。

{% for call in calls %}
    <tr class="{% cycle 'odd' 'even' %}"><h3>
        <td valign="middle" align="center"><h3>{{ call.calldate }}</h3></td>
        <td valign="middle" align="center"><h3>{{ call.disposition }}</h3></td>
        <td valign="middle" align="center"><h3>{{ call.dst }}</h3></td>
        <td valign="middle" align="center"><h3>{{ call.billsec }}</h3></td>
        <td valign="middle" align="center">{{ (call.billsec/60)*0.16 }}</td></h3>
    </tr>
{% endfor %}

最後は値を表示する必要があるところです。「(call.billsec / 60)*0.16」はそこでは不可能です。見せたいものを表現するためだけに書いた。

4

3 に答える 3

4

あなたは3つの異なる層でそれを行うことができます:

  • データベースレベル。SQLは数学が可能な強力な言語です。クエリの選択した部分に方程式を書くことができます。あなたの場合、それは線に沿っているはずSELECT (duration/60*0.16) FROM cdr;です。例はこことGoogleで見つけることができます。この場合、Pythonプロセスではなく、MySQLサーバープロセスにストレス(アルゴリズムの複雑さ)がかかることに注意してください。
  • ビューレベル。あなたの例では、戻る直前に、result変数のすべての要素をループしてその値を変更できます。このレベルでLieRyanによって与えられた例に従うことができます。
  • テンプレートレベル。これは、カスタムフィルターによって行われます。ドキュメントに記載されているようにカスタムフィルターを記述し、テンプレート変数をこのフィルターにパイプして、目的の値を取得できます。

これらの線に沿ったものは、テンプレートに適用可能なカスタムフィルターを表します。

@register.filter
def customFilter(value):
    return value / 60.0 * 0.16

{% load %}次に、カスタムフィルタを実行した後、テンプレートでこのように使用します(実装情報の詳細については、ドキュメントを参照してください)。

{{ billsec|customFilter }}
于 2012-09-02T05:23:05.830 に答える
3

数学演算がそれほど複雑でない場合、私は通常を使用しますcustom template tags追加操作はすでにテンプレートタグとして利用可能であり、プロジェクトでは以下のスニペットをそれぞれ乗算、減算、除算に使用しています。このコードを現在地内の.pyファイル内に配置し、そこにapp/templatetagsを追加し__init__.pyます。

from django import template

#Django template custom math filters
#Ref : https://code.djangoproject.com/ticket/361
register = template.Library()

def mult(value, arg):
    "Multiplies the arg and the value"
    return int(value) * int(arg)

def sub(value, arg):
    "Subtracts the arg from the value"
    return int(value) - int(arg)

def div(value, arg):
    "Divides the value by the arg"
    return int(value) / int(arg)

register.filter('mult', mult)
register.filter('sub', sub)
register.filter('div', div)
于 2012-09-02T14:37:29.693 に答える
1

編集:OPがsqliteを使用していると思ったので、次の答えは完全に間違っています。MySQLには、物事を辞書にラップする独自の方法があります。以下を参照してください。

sqlite3.Rowをサブクラス化して、独自の「計算フィールド」を作成できます。

class MyRow(sqlite3.Row):
    def comp_billsec(self):
        return (self['billsec'] / 60) * 0.16

cursor = ...
cursor.row_factory = MyRow
for r in cursor.execute('...'):
    print r['billsec'], r.comp_billsec()

ファクトリはディクショナリ構文を介したアクセスを提供しcomp_billsecますが、メソッド呼び出し構文を使用してアクセスされることに注意してください。sqlite3.Rowdjangoテンプレート内では、ディクショナリアクセスと引数なしの関数呼び出しの構文が同じであるため、この不一致はdjangoテンプレートでは解消され{{ call.billsec }}ます{{ call.comp_billsec }}

編集:MySQLでは、次の行に沿ってビューに計算値を挿入できます。

cursor = connections['cdr'].cursor(cursorclass=MySQLdb.cursors.DictCursor)
calls = cursor.execute("...")
result = [r + dict(comp_billsec=r['billsec'] / 60 * 0.16) for r in cursor.fetchall()]
return render_to_response("cdr_user.html",
    {'calls':result }, context_instance=RequestContext(request))

さらに、パラメーター化されたクエリを使用する必要があります(%の代わりにコンマに注意してください)。

cursor.execute("SELECT * FROM cdr where calldate > '%s'", (start_date,))

start_dateをSQLクエリに直接補間しているため、以前のコードはSQLインジェクションのセキュリティ問題の影響を受けます。たとえば、 start_dateにが含まれている場合' OR 1 OR '、クエリは補間さSELECT * FROM cdr where calldate > '' OR 1 OR ''れ、テーブル内のすべての行が選択されます。さらに悪化する可能性があります。

于 2012-09-02T04:03:16.457 に答える