这是我正在使用的Django模型。
class Person(models.Model):
surname = models.CharField(max_length=255, null=True, blank=True)
first_name = models.CharField(max_length=255, null=True, blank=True)
middle_names = models.CharField(max_length=255, null=True, blank=True)
birth_year = WideYear(null=True, blank=True)
birth_year_uncertain = models.BooleanField()
death_year = WideYear(null=True, blank=True)
death_year_uncertain = models.BooleanField()
flourit_year = WideYear(null=True, blank=True)
flourit_year_uncertain = models.BooleanField()
FLOURIT_CHOICES = (
(u'D', u'Birth and death dates'),
(u'F', u'Flourit date'),
)
use_flourit = models.CharField('Date(s) to use', max_length=2, choices=FLOURIT_CHOICES)
def __unicode__(self):
if str(self.birth_year) == 'None':
self.birth_year = ''
if str(self.death_year) == 'None':
self.death_year = ''
if str(self.flourit_year) == 'None':
self.flourit_year = ''
if self.use_flourit == u'D':
return '%s, %s %s (%s - %s)' % (self.surname, self.first_name, self.middle_names, self.birth_year, self.death_year)
else:
return '%s, %s %s (fl. %s)' % (self.surname, self.first_name, self.middle_names, self.flourit_year)
模型的__unicode__方法中的这段代码看起来相当冗长:
if str(self.birth_year) == 'None':
self.birth_year = ''
if str(self.death_year) == 'None':
self.death_year = ''
if str(self.flourit_year) == 'None':
self.flourit_year = ''
它的目的是阻止__unicode__方法返回类似
的内容默多克,鲁珀特(1931年 - 无)
并确保该方法返回类似
的内容默多克,鲁珀特(1931 - )
有没有办法以某种方式“泛化”那段代码,例如使用通配符,以便处理 self 对象的所有属性?
这样的事情:
if str(self.(*)) == 'None':
self.$1 = ''
在这里,我刚刚使用正则表达式语法来说明我的意思;显然,它不是python代码。本质上,我们的想法是循环遍历每个属性,检查它们的str()表示是否等于'None',如果是,则将它们设置为''。但如果能够比设置for循环更简洁,那就太好了。
答案 0 :(得分:5)
for n in dir(self):
if getattr(self, n) is None:
setattr(self, n, '')
我正在使用正常的is None
成语,假设你正在使用的那个奇怪的替代方案没有超级动机,但这是一个单独的问题; - )
编辑:如果你正在使用一个充满非常黑魔法的框架,比如Django,完全正常的Python方法突然可能会变得充满 - 因为OP似乎已经用类似的方式表示 - 莫名的编辑。好吧,如果Django的黑暗深层元素不能让它工作(尽管我不能像OP报告的那样重现这个问题),总有其他选择。特别是,因为这是在一个不应该改变对象(__unicode__
,特别是)的特殊方法中发生的,所以我推荐一个简单的辅助函数(一个简单的旧的独立模块级函数!):
def b(atr): return atr or u''
使用如下:
def __unicode__(self):
if self.use_flourit == u'D':
return '%s, %s %s (%s - %s)' % (
b(self.surname), b(self.first_name), b(self.middle_names),
b(self.birth_year), b(self.death_year)
)
else:
return '%s, %s %s (fl. %s)' % (
b(self.surname), b(self.first_name), b(self.middle_names),
b(self.flourit_year)
)
请注意,在(A)您希望根据需要更改self
时(在__unicode__
,__str__
,__repr__
等转换器中),我的原始答案完全正常。 ..,你不应该!),和(B)你在一个不使用真正的深,黑,黑烟黑魔法的类(显然Django的模型超类正在打破绝对基本的东西,如{{1} },dir
和/或setattr
- 尽管即使有了这个假设,我也无法重现OP的某些特定症状。