2

私の使用例は、DB にクエリを保存し、時々それらを取得して評価する必要があるということです。これは、個別にカスタマイズされたクエリによって選択された Web サイトのコンテンツをすべてのユーザーが購読できるメーリング アプリに必要です。最も基本的な解決策は、生の SQL を保存し、それを で使用することRawQuerySetです。しかし、もっと良い解決策があるのだろうか?

4

3 に答える 3

3

一見すると、クエリ構築ジョブを他の人に渡すのは非常に危険です。なぜなら、彼らは何でもできるからです (データベース内のすべてのデータを削除したり、テーブル全体を削除したりすることさえできます)。

クエリの特定の部分を作成しても、SQL インジェクションに対してオープンです。これらすべての危険に問題がない場合は、次のことを試してください。

これは私が使用した古いスクリプトであり、ユーザーがクエリの特定の部分を設定できるようにします。基本は and を使っstring.Templateていますeval(悪の部分)

モデルを定義します。

class SomeModel(Model):
    usr = ForeingKey(User)
    ct = ForeignKey(ContentType) # we will choose related DB table with this
    extra_params = TextField() # store extra filtering criteria in here

ユーザーに属するすべてのクエリを実行しましょう。'username__iontains'を含むUserクエリがあるとします。extra_params is_staff

usr: 誰か

ct: ユーザー

extra_params: is_staff=$stff_stat, username__icontains='$uname'

$extra_params でプレースホルダーを定義します

from string import Template
for _qry in SomeModel.objects.filter(usr='somebody'): # filter somebody's queries
    cts = Template(_qry.extra_params) # take extras with Template
    f_cts = cts.substitute(stff_stat=True, uname='Lennon') # sustitute placeholders with real time filtering values 
    # f_cts is now `is_staff=True, username__icontains='Lennon'`
    qry = Template('_qry.ct.model_class().objects.filter($f_cts)') # Now, use Template again to place our extras into a django `filter` query. We also select related model in here with `_qry.ct.model_class()`
    exec_qry = qry.substitute(f_cts=f_cts)
    # now we have `User.objects.filter(is_staff=True, username__icontains='Lennon')
    query = eval(exec_qry) # lets evaluate it!

関連するすべてのインポートが完了Qしたら、extra_params で使用またはその他のクエリ構築オプションを使用します。また、他の方法を使用してフォームCreateUpdateクエリを作成することもできます。

Templateフォームの詳細については、こちらをご覧ください。しかし、私が言ったように。そのようなオプションを他のユーザーに与えるのは本当に危険です。

また、 Django Content Typeについて読む必要があるかもしれません

更新: @GillBates が述べたように、辞書構造を使用してクエリを作成できます。この場合、もう必要ありTemplateません。このようなデータ転送には json を使用できます (必要に応じて他のものも使用できます)。json を使用して外部ソースからデータを取得すると仮定すると、次のコードは上のコード ブロックからいくつかの変数を使用するスクラッチです。

input_data : '{"is_staff"=true, "username__icontains"="レノン"}'

import json
_data = json.loads(input_data)
result_set = _qry.ct.model_class().objects.filter(**_data)
于 2013-10-24T09:20:28.560 に答える