[英]How can I introspect properties and model fields in Django?
I am trying to get a list of all existing model fields and properties for a given object.我正在尝试获取给定对象的所有现有模型字段和属性的列表。 Is there a clean way to instrospect an object so that I can get a dict of fields and properties.
是否有一种干净的方法来内省对象,以便我可以获得字段和属性的字典。
class MyModel(Model)
url = models.TextField()
def _get_location(self):
return "%s/jobs/%d"%(url, self.id)
location = property(_get_location)
What I want is something that returns a dict that looks like this:我想要的是返回一个看起来像这样的字典:
{
'id' : 1,
'url':'http://foo',
'location' : 'http://foo/jobs/1'
}
I can use model._meta.fields
to get the model fields, but this doesn't give me things that are properties but not real DB fields.我可以使用
model._meta.fields
来获取模型字段,但这不会给我属性而不是真正的数据库字段的东西。
If you strictly want just the model fields and properties (those declared using property) then:如果您只需要模型字段和属性(使用属性声明的那些),那么:
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)
The only bit that's extra here is running through the class to find the fields that correspond to property descriptors.这里唯一额外的一点是遍历类以查找与属性描述符对应的字段。 Accessing them via the class gives the descriptor, whereas via the instance it gives you the values.
通过类访问它们会得到描述符,而通过实例它会给你值。
The trouble is you say you only want fields, but then complicate things by throwing properties into the mix.问题是你说你只想要字段,然后通过将属性加入混合使事情复杂化。 There isn't really any easy way in Python of distinguishing between a property and any other random method.
在 Python 中没有任何简单的方法来区分属性和任何其他随机方法。 This isn't anything to do with Django: it's simply that a property is just a method that is accessed via a descriptor.
这与 Django 没有任何关系:它只是一个属性只是一个通过描述符访问的方法。 Because any number of things in the class will also be descriptors, you'll have trouble distinguishing between them.
因为类中的任意数量的事物也将是描述符,所以您将难以区分它们。
Is there any reason why you can't define a list at the class level that contains all the properties you want, then just call getattr
on each of the elements?有什么理由不能在类级别定义一个包含所需所有属性的列表,然后只需在每个元素上调用
getattr
吗?
You should use the dir() function on your instance.您应该在实例上使用 dir() 函数。 Skipping whatever starts with '__' and than use getattr to get the value from your instance.
跳过以 '__' 开头的任何内容,然后使用 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)
This is how they do it in Django.这就是他们在 Django 中的做法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.