python 如何动态检索 Django 模型类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/411810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:03:24  来源:igfitidea点击:

How do I retrieve a Django model class dynamically?

pythondjangodjango-modelsdjango-queryset

提问by thebossman

Without having the full module path of a Django model, is it possible to do something like:

如果没有 Django 模型的完整模块路径,是否可以执行以下操作:

model = 'User' [in Django namespace]
model.objects.all()

...as opposed to:

...而不是:

User.objects.all().

EDIT: I am trying to make this call based on command-line input. Is it possible to avoid the import statement, e.g.,

编辑:我正在尝试根据命令行输入进行此调用。是否可以避免导入语句,例如,

model = django.authx.models.User

Without Django returning the error:

没有 Django 返回错误:

"global name django is not defined."

回答by Alasdair

For Django 1.7+, there is an applications registry. You can use the apps.get_modelmethod to dynamically get a model.

对于 Django 1.7+,有一个应用程序注册表。您可以使用该apps.get_model方法动态获取模型。

from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')

回答by Daniel Naab

I think you're looking for this:

我想你正在寻找这个:

from django.db.models.loading import get_model
model = get_model('app_name', 'model_name')

There are other methods, of course, but this is the way I'd handle it if you don't know what models file you need to import into your namespace. (Note there's really no way to safely get a model without first knowing what app it belongs to. Look at the source code to loading.py if you want to test your luck at iterating over all the apps' models.)

当然,还有其他方法,但如果您不知道需要将哪个模型文件导入到命名空间中,我将采用这种方法。(请注意,在不首先知道模型属于哪个应用程序的情况下,真的无法安全地获取模型。如果您想测试迭代所有应用程序模型的运气,请查看 loading.py 的源代码。)

Update for Django 1.7+:According to Django's deprecation timeline, django.db.models.loadinghas been deprecated in Django 1.7 and will be removed in Django 1.9. As pointed out in Alasdair's answer, In Django 1.7+, there is an applications registry. You can use the apps.get_modelmethod to dynamically get a model:

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')

回答by thebossman

from django.authx.models import User
model = User
model.objects.all()

回答by S.Lott

model = django.authx.models.User

? Django returns an error, "global name django is not defined."

模型 = django.authx.models.User

? Django 返回错误,“全局名称 django 未定义”。

Django does not return the error. Python does.

Django 不会返回错误。Python 可以。

First, you MUST import the model. You must import it with

首先,您必须导入模型。你必须用

from django.authx.models import User

Second, if you get an error that djangois not defined, then Django is not installed correctly. You must have Django on your PYTHONPATHor installed in your Python lib/site-packages.

其次,如果您收到django未定义的错误,则 Django 未正确安装。您PYTHONPATH的 Python 库/站点包中必须有 Django或已安装。

To install Django correctly, see http://docs.djangoproject.com/en/dev/intro/install/#intro-install

要正确安装 Django,请参阅http://docs.djangoproject.com/en/dev/intro/install/#intro-install

回答by cdleary

Classes are "first class" objects in Python, meaning they can be passed around and manipulated just like all other objects.

类是 Python 中的“第一类”对象,这意味着它们可以像所有其他对象一样被传递和操作。

Models are classes -- you can tell from the fact that you create new models using class statements:

模型就是类——您可以从使用 class 语句创建新模型的事实中看出:

class Person(models.Model):
    last_name = models.CharField(max_length=64)

class AnthropomorphicBear(models.Model):
    last_name = models.CharField(max_length=64)

Both the Personand AnthropomorphicBearidentifiers are bound to Django classes, so you can pass them around. This can useful if you want to create helper functions that work at the model level (and share a common interface):

无论是PersonAnthropomorphicBear标识符绑定到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))

So print_obj_by_last_namewill work with either the Personor AnthropomorphicBearmodels. Just pass the model in like so:

所以print_obj_by_last_name将与PersonAnthropomorphicBear模型一起使用。只需像这样传递模型:

print_obj_by_last_name(model=Person, last_name='Dole')
print_obj_by_last_name(model=AnthropomorphicBear, last_name='Fozzy')

回答by Hannes Ovrén

If you have the model name passed as a string I guess one way could be

如果您将模型名称作为字符串传递,我想一种方法可能是

modelname = "User"
model = globals()[modelname]

But mucking about with globals() might be a bit dangerous in some contexts. So handle with care :)

但是在某些情况下,使用 globals() 可能有点危险。所以要小心处理:)