Djangoモデルクラスを動的に取得するにはどうすればよいですか?
-
03-07-2019 - |
質問
Djangoモデルの完全なモジュールパスがなくても、次のようなことができます:
model = 'User' [in Django namespace]
model.objects.all()
...とは対照的に:
User.objects.all().
編集:コマンドライン入力に基づいてこの呼び出しをしようとしています。インポート文を回避することは可能ですか?例:
model = django.authx.models.User
エラーを返すDjangoなし:
"global name django is not defined."
解決
これを探していると思います:
from django.db.models.loading import get_model
model = get_model('app_name', 'model_name')
もちろん他の方法もありますが、名前空間にインポートする必要があるモデルファイルがわからない場合、これが私が処理する方法です。 (モデルがどのアプリに属しているかを最初に知ることなく、モデルを安全に取得する方法は実際にはないことに注意してください。すべてのアプリのモデルを繰り返しテストする場合は、loading.pyのソースコードを参照してください。)
Django 1.7+のアップデート: Djangoの廃止予定表、 django.db.models.loading
はDjango 1.7で廃止され、Django 1.9で削除されます。 Alasdairの回答で指摘されているように、
Django 1.7+では、アプリケーションレジストリ。 apps.get_model
メソッドを使用してモデルを動的に取得します:
from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
他のヒント
Django 1.7+には、アプリケーションレジストリがあります。 apps.get_model
動的にモデルを取得するメソッド。
from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
from django.authx.models import User
model = User
model.objects.all()
model = django.authx.models.User
? Djangoはエラーを返します" global 名前djangoは定義されていません。"
Djangoはエラーを返しません。 Pythonはそうします。
最初に、モデルをインポートする必要があります。インポートする必要があります
from django.authx.models import User
第二に、 django
が定義されていないというエラーが表示された場合、Djangoは正しくインストールされていません。 PYTHONPATH
にDjangoがインストールされているか、Python lib / site-packagesにインストールされている必要があります。
Djangoを正しくインストールするには、 http:// docsをご覧ください。 djangoproject.com/en/dev/intro/install/#intro-install
クラスは「ファーストクラス」ですPythonのオブジェクト。つまり、他のすべてのオブジェクトと同じように、オブジェクトを渡したり操作したりできます。
モデルはクラスです-クラスステートメントを使用して新しいモデルを作成するという事実から次のことがわかります:
class Person(models.Model):
last_name = models.CharField(max_length=64)
class AnthropomorphicBear(models.Model):
last_name = models.CharField(max_length=64)
Person
と AnthropomorphicBear
の両方の識別子はDjangoクラスにバインドされているため、それらを渡すことができます。これは、モデルレベルで機能する(および共通のインターフェイスを共有する)ヘルパー関数を作成する場合に役立ちます。
def print_obj_by_last_name(model, last_name):
model_name = model.__name__
matches = model.objects.filter(last_name=last_name).all()
print('{0}: {1!r}'.format(model_name, matches))
したがって、 print_obj_by_last_name
は、 Person
または AnthropomorphicBear
モデルで動作します。そのようにモデルを渡すだけです:
print_obj_by_last_name(model=Person, last_name='Dole')
print_obj_by_last_name(model=AnthropomorphicBear, last_name='Fozzy')
モデル名が文字列として渡されている場合、1つの方法があると思います
modelname = "User"
model = globals()[modelname]
しかし、globals()をいじるのは、一部の状況では少し危険かもしれません。慎重に処理してください:)