基于对象信息的模型中的逻辑

时间:2013-07-23 07:46:38

标签: django django-models django-forms

有没有办法将逻辑嵌入到Django的模型层中,使用来自对象其他字段的逻辑?这听起来很复杂,所以我写了一些示例代码。我不想使用继承,我的所有字段都是共享的,它会使事情过于复杂。

class Creature(models.Model):
    numberOfEyes = models.IntegerField()
    type = models.CharField(max_length=30, choices=TYPE_CHOICES)

这正是我想要完成的,不是为了工作

if self.numberOfEyes == 1:
    TYPE_CHOICES = (
     ('cyclops', 'cyclops')
)
else:
    TYPE_CHOICES = (
    # You get the idea
)

有没有办法在模型层嵌入这个逻辑?或者我必须在表单中定义它吗?

1 个答案:

答案 0 :(得分:0)

如果该字段确实在不同模型之间共享,我建议您使用继承。

但是,看起来您希望不同模型的选择不同,因此在这种情况下继承不起作用。

以下是一些选项:

  1. 为每个模型设置不同的type字段。如果您只有几个型号,那么这是一种方法,因为它很简单。

  2. 使用无证件的Django内部组件进行操作。即在_choices中设置__init__()我不建议这样做,因为如果Django更改此变量或如何使用变量,您的代码将会中断。无论如何,这里有一些伪代码:

    class Creature(models.Model):
    
        numberOfEyes = models.IntegerField()
        type = models.CharField(max_length=30)
    
        def __init__(self, *args, **kwargs):
              super(MyModel, self).__init__(*args, **kwargs)
              for f in self._meta.fields:
                  if f.name == "type":
                      f._choices = ('choice1', 'choice2')
    
  3. 使用元类来构建模型。元类是用于创建类的类。我甚至不会尝试为此提出Metaclass伪代码,因为它可能无法正常工作。 Django拥有自己的Metaclass和Metaclass继承很复杂。但我们的想法是在自定义Metaclass中创建类型字段,并使用类级别变量指定要用于类型字段的选项。这是使用自定义Metaclass的伪代码:

    class Creature(models.Model):
        __metaclass__ = MyMetaClass
    
        TYPE_CHOICES = ('choice1', 'choice2')
    
        numberOfEyes = models.IntegerField()
        type = models.CharField(max_length=30)