Python 将模型名称作为字符串传递的最佳实践
我有两个不同的模型,我希望在不同的时间通过公共字段名进行类似的过滤,因此我编写了一个上下文函数,通过将字符串作为参数用作模型名来处理这两个模型。现在我正在使用eval(),但直觉告诉我这是一个严重的错误。有没有比我描述的更像蟒蛇的方式 下面是我的代码目前的简略版本:Python 将模型名称作为字符串传递的最佳实践,python,django,django-views,django-context,Python,Django,Django Views,Django Context,我有两个不同的模型,我希望在不同的时间通过公共字段名进行类似的过滤,因此我编写了一个上下文函数,通过将字符串作为参数用作模型名来处理这两个模型。现在我正在使用eval(),但直觉告诉我这是一个严重的错误。有没有比我描述的更像蟒蛇的方式 下面是我的代码目前的简略版本: def reference_context(model, value): menu = main_menu() info = company_info() pages = get_list_or_404(ev
def reference_context(model, value):
menu = main_menu()
info = company_info()
pages = get_list_or_404(eval(model), category = value)
第二,有没有一种方法可以以类似的方式传递关键字,这样我就可以大致做到:
def reference_context(model, category, value):
menu = main_menu()
info = company_info()
pages = get_list_or_404(eval(model), eval(category) = value)
欢迎并大力鼓励对任何其他问题进行评论。如果它们来自同一模块(
models.py
),您可以使用getattr
检索模型类,并使用kwargs
(带双星号的dict)以这种方式:
from myapp import models
def reference_context(model, value):
menu = main_menu()
info = company_info()
pages = get_list_or_404(getattr(models, model), **{category: value})
如果它们来自同一个模块(
models.py
),则可以使用getattr
检索模型类,并使用kwargs
(带双星号的dict)以这种方式:
from myapp import models
def reference_context(model, value):
menu = main_menu()
info = company_info()
pages = get_list_or_404(getattr(models, model), **{category: value})
您可以使用
get_model
实用程序功能,该功能采用应用程序名称和型号名称
from django.db.models import get_model
User = get_model("auth", "User") # returns django.contrib.auth.models.User
您可以使用
get_model
实用程序功能,该功能采用应用程序名称和型号名称
from django.db.models import get_model
User = get_model("auth", "User") # returns django.contrib.auth.models.User
我真的不明白为什么需要将模型作为字符串传递—只需传递模型引用即可。例如
class ModelA(models.Model):
...
class ModelB(models.Model):
...
def reference_context(model, **kw):
menu = main_menu()
info = company_info()
pages = get_list_or_404(model, **kw)
# ...
在此设置中,您可以传递任何模型和您想要的任何查询,例如
reference_context(ModelA, category="Hello")
或
正如我在评论中解释的,如果您真的需要将字符串映射到模型,请使用显式注册表/映射。这可以防止人们操纵表单数据,从而允许他们创建一个用户,而不是一本“书”:
我真的不明白为什么需要将模型作为字符串传递—只需传递模型引用即可。例如
class ModelA(models.Model):
...
class ModelB(models.Model):
...
def reference_context(model, **kw):
menu = main_menu()
info = company_info()
pages = get_list_or_404(model, **kw)
# ...
在此设置中,您可以传递任何模型和您想要的任何查询,例如
reference_context(ModelA, category="Hello")
或
正如我在评论中解释的,如果您真的需要将字符串映射到模型,请使用显式注册表/映射。这可以防止人们操纵表单数据,从而允许他们创建一个用户,而不是一本“书”:
为什么需要将模型作为字符串而不是引用传递?例如,据我所知,引用上下文(MyModel、value)并不常见。在这种情况下,我会创建自己的显式名称注册->模型(一个简单的dict就可以)并使用它。这样,当有人在表单中注入“User”作为模型时,可以避免意外的安全问题。为什么需要将模型作为字符串而不是引用传递?例如,据我所知,引用上下文(MyModel、value)并不常见。在这种情况下,我会创建自己的显式名称注册->模型(一个简单的dict就可以)并使用它。这样,当有人在表单中注入“用户”作为模型时,可以避免意外的安全问题。