如何测试一个类是否包含特定属性?
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
我有一个奇怪的错误,其中显示的属性比我实际定义的要多。 我想有条件地阻止它。
e.g。
if not hasattr(User, 'karma'):
User.add_to_class('karma', models.PositiveIntegerField(default=1))
答案 0 :(得分:9)
据我所知,Django模型没有类似hasattr()的方法。但有一种方法可以检查Django模型是否具有某个字段。
为了测试这个,我建议你访问Django(Python)shell:
$> python manage.py shell
现在导入用户模型:
$> from django.contrib.auth.models import User
获取模型的元信息:
$> opts = User._meta
要检查字段,请使用以下命令:
$> opts.get_field('username')
如果是User模型,将打印出如下消息:
<django.db.models.fields.CharField object at 0x1024750>
如果您要查找的字段不是模型的一部分,则会抛出FieldDoesNotExist。有了这些知识,您应该能够以编程方式检查字段的存在。
您可以在此处详细了解:b-list.org: Working with models
答案 1 :(得分:7)
我同意关于EAFP的问题中的评论,但相反,当你需要LBYL(Look Before You Leap)时,有一些情况。
一般来说,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()
答案 2 :(得分:1)
User类没有具有username属性,因为模型字段是在初始化时由元类添加的。但您可以使用Model._meta.get_field(filename)
检查模型是否定义了特定字段。
答案 3 :(得分:0)
对于django 1.10及更高版本(不推荐使用get_all_field_names之后):
def get_or_create_field(self, field_name, type):
if field_name not in [f.name for f in self._meta.get_fields()]:
self.add_to_class(field_name, type)
return self._meta.get_field(field_name)