我有一个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中找到许多基本级别的信息。在这里,有许多链接可以在各种主题上进行扩展。除此之外,我相信这只需要一点想象力,也许一开始就需要反复尝试。