如何在 Django 中为我的所有模型编写 __str__ 方法的通用实现?
How to write common implementation of __str__ method for all my models in Django?
我希望我的所有模型都以类似的方式覆盖 __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)
但它通过用指向 ShowModel
的指针替换 id
来混淆 MyModel1
和 MyModel2
的 id
。如何在没有继承的情况下为我的模型编写 __str__
方法的通用实现,或者如何防止将 ShowModel
class 视为 Django 模型?
更新: 我按照 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'
Upd 如果我为模型对象的 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'
在测试用例中:
ua = MyModel1()
ua.name = 'hi'
print(ua)
#prints hi
ub = MyModel2()
ub.another_param = 'hi again'
print(ub)
#prints hi again
您需要创建一个 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,你应该在调用 hasattr()
和 getattr()
时将 self.to_show
替换为 "to_show"。
我希望我的所有模型都以类似的方式覆盖 __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)
但它通过用指向 ShowModel
的指针替换 id
来混淆 MyModel1
和 MyModel2
的 id
。如何在没有继承的情况下为我的模型编写 __str__
方法的通用实现,或者如何防止将 ShowModel
class 视为 Django 模型?
更新: 我按照 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'
Upd 如果我为模型对象的 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'
在测试用例中:
ua = MyModel1()
ua.name = 'hi'
print(ua)
#prints hi
ub = MyModel2()
ub.another_param = 'hi again'
print(ub)
#prints hi again
您需要创建一个 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,你应该在调用 hasattr()
和 getattr()
时将 self.to_show
替换为 "to_show"。