因此,我想将属性添加到类似于另一个模型的属性的模型中,该模型包含可翻译的字段。
我的模型:
class MyModel(models.Model):
... fields ...
class MyModelTranslation(models.Model):
... the fields I want on MyModel ...
name = models.CharField()
city = models.CharField()
language = models.CharField()
mymodel = models.ForeignKey(MyModel)
所以我写了以下__init__
class MyModel(models.Model):
...
def __init__(self, *args, **kwargs):
super(Model, self).__init__(*args, **kwargs)
# get_translation gets the object, that holds the translation fields for the
# current active language
trans = lambda c: c.get_translation()
setattr(self.__class__, 'translation', property(trans))
fget = lambda c: getattr(trans(c), 'name')
fset = lambda c, v: setattr(trans(c), 'name', v)
setattr(self.__class__, 'name', property(fget, fset))
fget = lambda c: getattr(trans(c), 'city')
fset = lambda c, v: setattr(trans(c), 'city', v)
setattr(self.__class__, 'city', property(fget, fset))
这完美地工作。然后当我打电话时mymodel.name
,我得到mymodeltranslation.name
了活动语言。也可以设置此值。
由于我希望动态生成它以便可以在 mixin 中使用它,因此我将它添加到 for 循环中,如下所示:
def __init__(self, *args, **kwargs):
super(Model, self).__init__(*args, **kwargs)
trans = lambda c: c.get_translation()
setattr(self.__class__, 'translation', property(trans))
# returns all fields of the translation model
trans_fields = [field.name for field in [
related for related in self._meta.get_all_related_objects()
if "translation" in related.name
][0].model._meta.fields]
# should then assign all those fields dynamically
for name in trans_fields:
if not name == 'id' and not name == 'mymodel':
fget = lambda c: getattr(trans(c), name)
fset = lambda c, v: setattr(trans(c), name, v)
setattr(self.__class__, name, property(fget, fset))
所以我想,好吧,因为这个name
值类似于我以前手动添加的字段的名称,所以它应该在每次运行 for 循环时添加property
一个名称为 的值。name
但事实并非如此。当我调用mymodel.name
它时,它会返回模型实例(基本上就是这样self
)。当我在 forloop 中而不是全部手动执行时,我不知道有什么不同。
有任何想法吗?