【问题标题】:Django: Dynamic model field definitionDjango:动态模型字段定义
【发布时间】:2012-01-06 17:50:42
【问题描述】:

你好 Stackoverflow 的人,

我有一个相当单调的模型定义,它包括从 1 到 50 的 bin 字段。

为了概念验证,我是手工编写的,但必须有更好的方法来自动化模型定义并保持代码整洁。

到目前为止,我是按照以下方式完成的:

class Bins(models.Model):
    p1 = models.DecimalField(_('bin 1'), max_digits=6, decimal_places=2)
    p2 = models.DecimalField(_('bin 2'), max_digits=6, decimal_places=2)
    p3 = models.DecimalField(_('bin 3'), max_digits=6, decimal_places=2)
    ...
    p50 = ...

Django wiki上,我找到了动态模型定义的摘要,但它似乎不允许定义中的for循环:

我已经尝试了下面的代码,但我收到一条错误消息,指出 MAX_BIN = 2 是无效的语法。 我了解无法像我尝试的那样迭代该字段的错误。

Bins = type('Bins', (models.Model,), {     
    MAX_BIN = 50
    for i in range(MAX_BIN):
        name_sects = ["p", str(i)]
        "".join(name_sects): model.DecimalField(_("".join([bin ', str(i)])),
                             max_digits=6, decimal_places=2)
    })

这样的动态类定义一般可行吗? 如果是这样,定义类的最佳方法是什么?

感谢您的帮助!

【问题讨论】:

标签: django dynamic model field


【解决方案1】:

在您当前的版本中,您的循环位于字典的定义中。这是不允许的。但是,您可以在调用 type 之外的字典中定义您的字段,这样可以正常工作。像

attrs = {
    other_field = models.IntegerField(),
    '__module__': 'myapp.models',
}

MAX_BIN = 50
   for i in range(MAX_BIN):
       name_sects = ["p", str(i)]
        attrs["".join(name_sects)] = model.DecimalField(_("".join(['bin ', str(i)])),
            max_digits=6, decimal_places=2)

Bins = type('Bins', (models.Model,), attrs)

【讨论】:

  • 感谢您的回答!该代码似乎解决了问题,但是当我执行它时,我收到以下错误消息:“KeyError:'myapp.model'”(我已将“myapp”更改为我的模型名称)。错误的原因是什么?
  • myapp 是您的应用程序的名称,它在installed_apps 中吗?
  • 感谢您的提示。我忘了提及 settings.py 中所述的文件夹:apps.myapp.models。谢谢您的回答!非常好的解决方案。
【解决方案2】:

解决相同问题的简单解决方案:

class Bins(models.Model):
    MAX_BIN = 50
    for i in xrange(1, MAX_BIN + 1):
        vars()['p' + str(i)] = models.DecimalField('bin ' + str(i),
            max_digits=6, decimal_places=2)

【讨论】:

    猜你喜欢
    • 2011-12-17
    • 2014-04-16
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 2011-02-05
    • 2012-06-05
    相关资源
    最近更新 更多