2011-02-08 3 views
7

Я пытаюсь получить список всех существующих полей модели и свойств для данного объекта. Есть ли чистый способ подвергнуть объект объекту, чтобы я мог получить диктовку полей и свойств.Как я могу исследовать свойства и поля модели в Django?

class MyModel(Model) 
    url = models.TextField() 

    def _get_location(self): 
     return "%s/jobs/%d"%(url, self.id) 

    location = property(_get_location) 

То, что я хочу, это то, что возвращает Dict, который выглядит следующим образом:

{ 
    'id' : 1, 
    'url':'http://foo', 
    'location' : 'http://foo/jobs/1' 
} 

я могу использовать model._meta.fields, чтобы получить модель поля, но это не дает мне вещи, которые являются свойствами, но а не реальные поля БД.

ответ

8

Если вы строго хотите только модели поля и свойства (объявленных с использованием имущества), то:

 
def get_fields_and_properties(model, instance): 
    field_names = [f.name for f in model._meta.fields] 
    property_names = [name for name in dir(model) if isinstance(getattr(model, name), property)] 
    return dict((name, getattr(instance, name) for name in field_names + property_names) 

instance = MyModel() 
print get_fields_and_properties(MyModel, instance) 

Единственный бит, что лишняя здесь работает через класса найти поля, которые соответствуют свойству дескрипторы. Доступ к ним через класс дает дескриптор, тогда как через экземпляр он дает вам значения.

+0

Спасибо - это именно то, что мне нужно. Я пытался искать вещи типа «свойство» внутри экземпляра, но я должен был искать их в классе. – shreddd

0

Вы должны использовать функцию dir() на вашем экземпляре. Пропуск, начинающийся с '__', и использование getattr для получения значения из вашего экземпляра.

properties = [prop for prop in dir(SomeClass) if not prop.startswith("__")] 

obj = {} 
for prop in properties: 
    obj[prop] = getattr(myinstance, prop) 
+0

Не работает для моделей Django. Существует множество других методов и переменных, доступных объекту (унаследованных от базового класса Django Model), но не являются строго полями Django или свойствами. Мне нужно уметь различать свойства/поля и другие вещи. – shreddd

+0

Чтобы уточнить - я имею в виду встроенное свойство «http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/»), а не только общий атрибут python объект. – shreddd

+0

@shreddd: Сравните то, что у вас есть с model._meta.fields, чтобы различать поля db и свойства. –

1

Проблема в том, что вы говорите, что хотите только поля, но затем усложняете вещи, бросая свойства в микс. В Python нет никакого простого способа различать свойство и любой другой случайный метод. Это не имеет ничего общего с Django: просто свойство - это просто метод, доступ к которому осуществляется через дескриптор. Поскольку любое количество вещей в классе также будет дескрипторами, вам будет трудно различать их.

Есть ли причина, по которой вы не можете определить список на уровне класса, который содержит все необходимые свойства, а затем просто вызовите getattr по каждому из элементов?

0
class Awesome(models.Model): 
foo = models.TextField() 
bar = models.CharField(max_length = 200) 

awe = Awesome() 
for property in awe.__dict__.copy(): 
# pass private properties. 
if not property.startswith('_'): 
    print property,getattr(awe,property) 

Вот как они это делают в Django.

+1

Это все меняет внутри dict, но не то, что объявлено с помощью свойства(). Похоже, мне нужно пойти и извлечь это из класса модели напрямую. См. Решение Джона Монтгомери выше. – shreddd

Смежные вопросы