Django模型上的内省属性类型没有'对象'抛出AttributeError

时间:2015-02-24 23:00:59

标签: python django introspection

这听起来像是重复的,但我绝对找不到有问题重复的人。

我的模特:

class SuperCoolModel(models.Model):
    large = models.ImageField()
    small = models.ImageField()
    blah = some.OtherClass()  # Not a Field type, but is a subclass of ImageFile

想要做的是对这个模型的实例上的属性进行“迭代”(以某种方式),并为属于ImageField实例的属性执行某些操作。

例如,这里的代码有效

from django.db.models.fields.files import ImageFile
a = SuperCoolModel.objects.get(pk=1)
for attrname in dir(a):
    # Ignore attr names that we obviously don't care about:
    # E.g., anything that starts with an underscore-or-two:
    if attrname.startswith('_'):
        continue
    try:
        if isinstance(getattr(a, attrname), ImageFile):
            field = getattr(a, attrname)
            # Manipulate some stuff, based on the file, 
            # e.g., using `field.path`.
            pass 
    except AttributeError as e:
        # Hopefully this is JUST the 'objects' reference?
        pass

在上面的例子中,当它遍历方法/属性名称时,当它到达'object'时它引发:

  File "<console>", line 3, in <module>   File "/path/to/lib/python2.7/site-packages/django/db/models/manager.py", line 206, in __get__
    raise AttributeError("Manager isn't accessible via %s instances" % type.__name__)
AttributeError: Manager isn't accessible via SuperCoolModel instances

...所以我开始关注AttributeError例外。或者,我可以在循环中对“对象”进行硬编码,就像检查下划线名称时一样。

我不能使用a._meta.fieldsa._meta.get_all_field_names()等,因为我也在尝试检查某些不是字段但是某个子类和/或类型的

我这样做是对的,还是有更好的方法可以跳过“对象”(和其他潜在的“陷阱”)?

1 个答案:

答案 0 :(得分:1)

我不理解你为什么不能使用_meta方法的解释:你可以使用a._meta.get_all_field_names()来获取实际字段的列表,然后添加任意字段您对结果列表的属性。

在即将发布的1.8版本中,已弃用此版本,您需要使用[f.name for f in a._meta.get_fields()]

请注意,属性的 none 将是ImageField的一个实例。该实例没有ImageFields(或CharFields,或任何字段)作为属性;它有实际的字符串,整数等,对于图像,它使用FieldFile