如何测试以查看某个类是否包含特定属性?

时间:2010-04-25 15:42:50

标签: python django reflection

如何测试一个类是否包含特定属性?

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)) 

4 个答案:

答案 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)
相关问题