Как я могу проанализировать свойства и поля модели в Django? - PullRequest
8 голосов
/ 08 февраля 2011

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

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

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

    location = property(_get_location)

То, что я хочу, - это то, что возвращает слово, похожее на это:

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

Ответы [ 4 ]

10 голосов
/ 08 февраля 2011

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

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)

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

1 голос
/ 08 февраля 2011

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

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

0 голосов
/ 08 февраля 2011
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)

Вот как они это делают в Джанго.

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

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

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

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