2

我正在使用 getattr 像这样动态访问模型的属性(假设 Student 模型有一个名为 name 的属性):

students = Student.objects.all()
property = 'name'


for student in students:
    print getattr(student, property)

这很好用,但是我想知道是否可以以相同的方式访问相关记录的属性,例如(假设每个学生都有一个相关组,其属性名为 title):

students = Student.objects.selected_related()
property = 'group.title'


for student in students:
    print getattr(student, property)

有了这个,我只得到错误'学生没有属性 group.title'

有没有办法做到这一点?

任何建议表示赞赏。

谢谢

4

4 回答 4

6

虽然以下代码将按照您的要求执行:

students = Student.objects.all()
attr_chain = "group.title".split(".")

for student in students:
    item = student
    for attr in attr_chain:
        item = getattr(item, attr)

    print "%s is in the group %s" % (student, item)

根据您的需要,我建议您values_list在 Queryset 类上查看 Django 的函数,它可以在许多情况下缩短和简化代码。

name_attr = "name"

#If you look in the documentation you will see why I use "__" here
group_title_attr = "group__title" 

for student_name, group_title in Student.objects.all().values_list(name_attr, group_title_attr):
    print "%s is in the group %s" % (student_name, group_title)

相关文档在这里这里

于 2012-01-06T02:22:33.947 回答
3

looks like you are looking for

getattr(getattr(student, property), subproperty)

you may be able to do with by looping over property.split('.')

于 2012-01-05T23:39:25.377 回答
2

你可以随时使用from functools import reduce

并像这样处理:

reduce(getattr, "some.nested.property".split("."), student)
于 2015-07-15T07:50:51.343 回答
0

除非 select_related 中的每个对象都有一个名为“title”的属性,否则它会爆炸。select_related 为 Student 模型带来了什么?我猜它不仅仅是一个 Group 对象。您需要将其包装在 try/except 块中或测试对象以查看它是否与 Group 的类型相同(例如,isinstance(x, Group))。

你到底想达到什么目的?这似乎有点受折磨。另外,我建议重新标记以使事情更清楚:

for obj in student_related:
    # print type(obj)
    print getattr(obj, property)

您实际上并没有在该列表中获取 Student 对象。

于 2012-01-05T23:40:43.003 回答