我正在尝试获取给定对象的所有现有模型字段和属性的列表。是否有一种干净的方式来检查一个物体,以便我可以得到一个字段和属性的字典。
class MyModel(Model)
url = models.TextField()
def _get_location(self):
return "%s/jobs/%d"%(url, self.id)
location = property(_get_location)
我想要的是返回一个看起来像这样的字典:
{
'id' : 1,
'url':'http://foo',
'location' : 'http://foo/jobs/1'
}
我可以使用model._meta.fields
来获取模型字段,但这不会给我属性但不是真正的数据库字段。
答案 0 :(得分:10)
如果您只想要模型字段和属性(使用属性声明的那些),那么:
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 :(得分:1)
麻烦的是你说你只想要字段,但是通过将属性投入混合来使事情变得复杂。 Python中没有任何简单的方法可以区分属性和任何其他随机方法。这与Django没有任何关系:它只是一个属性只是一个通过描述符访问的方法。因为类中的任何数量的东西也都是描述符,所以你很难区分它们。
您是否有任何理由无法在包含所需属性的类级别定义列表,那么只需在每个元素上调用getattr
?
答案 2 :(得分:0)
您应该在实例上使用dir()函数。跳过以'__'开头的内容,而不是使用getattr从您的实例中获取值。
properties = [prop for prop in dir(SomeClass) if not prop.startswith("__")]
obj = {}
for prop in properties:
obj[prop] = getattr(myinstance, prop)
答案 3 :(得分: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中的表现。