Как я могу проверить, содержит ли класс определенный атрибут? - PullRequest
3 голосов
/ 25 апреля 2010

Как я могу проверить, содержит ли класс определенный атрибут?

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  

У меня странная ошибка, когда появляется больше атрибутов, чем я на самом деле определяю. Я хочу условно прекратить это.

, например

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

Ответы [ 4 ]

9 голосов
/ 25 апреля 2010

Насколько я знаю, не существует такого метода, как hasattr () для моделей Django. Но есть способ проверить, имеет ли модель Django определенное поле.

Чтобы проверить это, я бы порекомендовал вам получить доступ к оболочке Django (Python):

$> python manage.py shell

Теперь импортируйте модель User:

$> 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: Работа с моделями

7 голосов
/ 25 апреля 2010

Я согласен с комментариями, сделанными в вопросе о 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()
1 голос
/ 25 апреля 2010

Класс пользователя не не имеет атрибута имени пользователя, потому что поля модели добавляются метаклассом во время инициализации. Но вы можете проверить, что модель определяет определенное поле, используя Model._meta.get_field(filename).

0 голосов
/ 08 февраля 2017

Для 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...