如何测试一个类是否包含特定属性?
我该怎么测试一个类里是否包含某个特定的属性呢?
In [14]: user = User.objects.get(pk=2)
In [18]: user.__dict__
Out[18]:
{'date_joined': datetime.datetime(2010, 3, 17, 15, 20, 45),
'email': u'IloveDick@nwo.gov',
'first_name': u'',
'id': 2L,
'is_active': 1,
'is_staff': 0,
'is_superuser': 0,
'last_login': datetime.datetime(2010, 3, 17, 16, 15, 35),
'last_name': u'',
'password': u'sha1$44a2055f5',
'username': u'DickCheney'}
In [25]: hasattr(user, 'username')
Out[25]: True
In [26]: hasattr(User, 'username')
Out[26]: False
我遇到了一个奇怪的bug,结果显示的属性比我实际定义的要多。我想有条件地停止这个情况。
比如说:
if not hasattr(User, 'karma'):
User.add_to_class('karma', models.PositiveIntegerField(default=1))
4 个回答
1
User类没有用户名这个属性,因为模型的字段是在初始化时由元类添加的。不过,你可以通过使用Model._meta.get_field(filename)
来检查一个模型是否定义了某个特定的字段。
7
我同意问题中关于EAFP(尽信则疑)的评论,但另一方面,有些情况下你需要采取LBYL(先看后跳)的方式。
对于Python类的一般方法在Django模型中不太适用,因为Django的元类魔法使得字段并不包含在模型类的__dict__
中。所以,针对Django模型,你可以使用下面这样的函数:
def django_model_has_field(model_class, field_name):
return field_name in model_class._meta.get_all_field_names()
9
据我所知,Django模型没有像hasattr()这样的检查方法。不过,有一种方法可以检查Django模型是否有某个字段。
为了测试这个,你可以打开Django的(Python)命令行工具:
$> python manage.py shell
接下来,导入用户模型:
$> from django.contrib.auth.models import User
获取模型的元信息:
$> opts = User._meta
要检查某个字段,可以使用以下命令:
$> opts.get_field('username')
如果是用户模型,系统会打印出类似这样的信息:
<django.db.models.fields.CharField object at 0x1024750>
如果你要查找的字段不在模型中,就会出现一个FieldDoesNotExist的错误。掌握了这些知识后,你就可以通过编程的方式检查字段是否存在了。
你可以在这里了解更多信息: b-list.org: Working with models