私の使用例は、DB にクエリを保存し、時々それらを取得して評価する必要があるということです。これは、個別にカスタマイズされたクエリによって選択された Web サイトのコンテンツをすべてのユーザーが購読できるメーリング アプリに必要です。最も基本的な解決策は、生の SQL を保存し、それを で使用することRawQuerySet
です。しかし、もっと良い解決策があるのだろうか?
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 で使用またはその他のクエリ構築オプションを使用します。また、他の方法を使用してフォームCreate
やUpdate
クエリを作成することもできます。
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)