如何为Django中的所有模型编写__str__方法的通用实现?

时间:2016-08-31 15:53:12

标签: python django inheritance django-models abstract

我希望我的所有模型都以类似的方式覆盖__str__方法:

class MyModel1(models.Model):
    name = models.CharField(max_length=255)

    def __init__(self):
        self.to_show = 'name'

    def _show(self):
        if hasattr(self,self.to_show):
            return str(getattr(self, self.to_show))
        else:
            return str(getattr(self, 'id'))

    def __str__(self):
        return self._show()

class MyModel2AndSoOn(models.Model):
    another_param = models.CharField(max_length=255)
    # same implementation of `__str__` but with another_param

我不想为我的所有模型重复相同的代码,所以我尝试了继承:

class ShowModel(models.Model):
    name = models.CharField(max_length=255)

    def __init__(self):
        self.to_show = 'name'

    def _show(self):
        if hasattr(self,self.to_show):
            return str(getattr(self, self.to_show))
        else:
            return str(getattr(self, 'id'))

    def __str__(self):
        return self._show()

class MyModel1(ShowModel):
    another_param = models.CharField(max_length=255)

class MyModel2(ShowModel):
    another_param = models.CharField(max_length=255)

但它与idMyModel1的{​​{1}}混淆,用MyModel2替换id。如何为没有继承的模型编写ShowModel方法的通用实现,或者如何防止将__str__类视为Django模型?

更新:我使用了ShowModel模型作为alecxe建议,但最终收到了错误消息:

abstract

更新如果我将值分配给模型对象的in _show return str(getattr(self, self.to_show)) File "/path/to/my/project/env3/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 188, in __str__ model = self.model AttributeError: 'CharField' object has no attribute 'model' 字段,那么一切正常。整体解决方案:

name

在测试用例中:

class ShowModel(object):
    to_show = 'name'

    def _show(self):
            if hasattr(self,self.to_show):
                return str(getattr(self, self.to_show))
            elif hasattr(self,'id'):
                return str(getattr(self, 'id'))
            else:
                return str(self)

    def __str__(self):
         return self._show()

    class Meta:
        abstract = True

class MyModel1(ShowModel):
    name = models.CharField(max_length=255)
    to_show = 'name'

class MyModel2(ShowModel):
    another_param = models.CharField(max_length=255)
    to_show = 'another_param'

1 个答案:

答案 0 :(得分:1)

您需要创建abstract model

class ShowModel(models.Model):
    name = models.CharField(max_length=255)

    def __init__(self):
        self.to_show = 'name'

    def _show(self):
        if hasattr(self, "to_show"):
            return str(getattr(self, "to_show"))
        else:
            return str(getattr(self, 'id'))

    def __str__(self):
        return self._show()

    class Meta:
        abstract = True

至于你的后续问题,感谢@itzmeontv,你应该用" to_show"替换self.to_show。致电hasattr()getattr()时。