[英]How can I introspect properties and model fields in Django?
我正在尝试获取给定对象的所有现有模型字段和属性的列表。 是否有一种干净的方法来内省对象,以便我可以获得字段和属性的字典。
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
来获取模型字段,但这不会给我属性而不是真正的数据库字段的东西。
如果您只需要模型字段和属性(使用属性声明的那些),那么:
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)
这里唯一额外的一点是遍历类以查找与属性描述符对应的字段。 通过类访问它们会得到描述符,而通过实例它会给你值。
问题是你说你只想要字段,然后通过将属性加入混合使事情复杂化。 在 Python 中没有任何简单的方法来区分属性和任何其他随机方法。 这与 Django 没有任何关系:它只是一个属性只是一个通过描述符访问的方法。 因为类中的任意数量的事物也将是描述符,所以您将难以区分它们。
有什么理由不能在类级别定义一个包含所需所有属性的列表,然后只需在每个元素上调用getattr
吗?
您应该在实例上使用 dir() 函数。 跳过以 '__' 开头的任何内容,然后使用 getattr 从您的实例中获取值。
properties = [prop for prop in dir(SomeClass) if not prop.startswith("__")]
obj = {}
for prop in properties:
obj[prop] = getattr(myinstance, prop)
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 中的做法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.