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

Bry*_*ock 3 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  
Run Code Online (Sandbox Code Playgroud)

我有一个奇怪的错误,其中显示的属性比我实际定义的要多.我想有条件地阻止这个.

例如

if not hasattr(User, 'karma'):
  User.add_to_class('karma', models.PositiveIntegerField(default=1)) 
Run Code Online (Sandbox Code Playgroud)

Jen*_*ens 9

据我所知,Django模型没有类似hasattr()的方法.但是有一种方法可以检查Django模型是否具有某个字段.

为了测试这个,我建议你访问Django(Python)shell:

$> python manage.py shell
Run Code Online (Sandbox Code Playgroud)

现在导入用户模型:

$> from django.contrib.auth.models import User
Run Code Online (Sandbox Code Playgroud)

获取模型的元信息:

$> opts = User._meta
Run Code Online (Sandbox Code Playgroud)

要检查字段,请使用以下命令:

$> opts.get_field('username')
Run Code Online (Sandbox Code Playgroud)

如果是User模型,将打印出如下消息:

<django.db.models.fields.CharField object at 0x1024750>
Run Code Online (Sandbox Code Playgroud)

如果您要查找的字段不是模型的一部分,则会抛出FieldDoesNotExist.有了这些知识,您应该能够以编程方式检查字段的存在.

你可以在这里阅读更多相关信息:b-list.org:使用模型


Vin*_*jip 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()
Run Code Online (Sandbox Code Playgroud)