我有一个django模型,其中有很多字段是可选的。所以我不得不写很多类的“is something”属性来检查实例值是否等于某个选择值。大致如下:

class MyModel(models.Model):
    some_choicefield = models.IntegerField(choices=SOME_CHOICES)

    @property
    def is_some_value(self):
        return self.some_choicefield == SOME_CHOICES.SOME_CHOICE_VALUE

    # a lot of these...

为了实现自动化并节省大量的冗余代码,我考虑在创建时修补实例,使用一个函数添加一组执行检查的方法。
代码如下所示(我假设有一个“normalize”函数使所选的标签成为可用的函数名):
def dynamic_add_checks(instance, field):
    if hasattr(field, 'choices'):
        choices = getattr(field, 'choices')
        for (value,label) in choices:
            def fun(instance):
                return getattr(instance, field.name) == value
            normalized_func_name = "is_%s_%s" % (field.name, normalize(label))
            setattr(instance, normalized_func_name, fun(instance))

class MyModel(models.Model):
    def __init__(self, *args, **kwargs):
        super(MyModel).__init__(*args, **kwargs)
        dynamic_add_checks(self, self._meta.get_field('some_choicefield')

    some_choicefield = models.IntegerField(choices=SOME_CHOICES)

现在,这是可行的,但我觉得有更好的办法。可能在类创建时(使用元类或在新方法中)你对此有什么想法/建议吗?

最佳答案

好吧,我不知道如何用你的方式来做,但在这种情况下,我认为方法是简单地创建一个新的模型,在那里你保留你的选择,并将字段更改为foreignkey。这更易于编码和管理。
您可以在Django docs: Models: Relationships中找到许多基本级别的信息。在这里,有许多链接可以在各种主题上进行扩展。除此之外,我相信这只需要一点想象力,也许一开始就需要反复尝试。

10-06 04:59
查看更多