2010-04-25 57 views
3

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

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'[email protected]', 
'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 

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

例如

if not hasattr(User, 'karma'): 
    User.add_to_class('karma', models.PositiveIntegerField(default=1)) 
+2

的Python遵循EAFP模式(更容易请求原谅比许可) - 地道的Python代码不应该检查属性的存在,它应该简单地假设它会在那里。 – 2010-04-25 15:48:27

+0

关于EAFP的更多信息:http://docs.python.org/glossary.html#term-eafp – 2010-04-25 15:56:50

回答

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

7

我同意关于EAFP问题提出的意见,但反过来也有一些情况下,当你需要LBYL(三思而后行)。

由于Django的元类魔术意味着字段不包含在模型类'__dict__中,因此一般来说,Python类的方法不适用于Django模型。因此,专门为Django模型,你可以这样做有以下功能:

def django_model_has_field(model_class, field_name): 
    return field_name in model_class._meta.get_all_field_names() 
+0

以上不再是可用的解决方案 – Zargold 2017-02-07 21:18:50

1

User类有一个用户名的属性,因为模型场由在初始化时元类添加。但是,您可以使用Model._meta.get_field(filename)来检查模型是否定义了特定字段。

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