0

我有两个不同的模型,我想在不同时间通过一个公共字段名称进行类似的过滤,所以我编写了一个上下文函数,通过将字符串作为参数用作模型名称来处理这两个模型。现在我正在使用 eval(),但我的直觉告诉我这是一个严重的错误。有没有更蟒蛇的方式来做我所描述的?

这是我的代码目前的简化版本:

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)

欢迎并大力鼓励对任何其他问题发表评论。

4

3 回答 3

1

如果它们来自同一个模块 ( 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})
于 2013-09-16T14:20:44.737 回答
1

您可以使用get_model实用程序函数,该函数采用应用程序名称和模型名称。

from django.db.models import get_model
User = get_model("auth", "User") # returns django.contrib.auth.models.User
于 2013-09-16T14:37:45.343 回答
1

我真的不明白为什么需要将模型作为字符串传递 - 只需传递模型引用即可。例如

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

或者

reference_context(ModelB, item__ordered__lte=now)

正如我的评论中所解释的,如果您确实需要将字符串映射到模型,请使用显式注册表/映射。这可以防止人们操纵可能允许他们创建用户而不是例如“书”的表单数据:

model_map = dict(book=ModelA, magazine=ModelB)
reference_context(model_map[model_as_string], ...)
于 2013-09-16T14:39:34.257 回答