2012-01-05 56 views
1

我使用GETATTR动态访问像这样一个模型的属性(假设学生模型有一个属性名为名):Django动态访问相关属性?

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


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

这工作得很好,但我不知道是否有可能访问以同样的方式相关的记录的特性,例如(假设每个学生都有一个属性称为标题相关组):

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


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

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

无论如何要实现这一目标吗?

任何意见赞赏。

感谢

+1

不要忘记检查,如果有问题的对象有你要找的属性与'hasattr'或处理当您尝试访问不存在的属性时,可能会出现异常。 – apiguy 2012-01-05 23:44:49

回答

3

虽然下面的代码会做什么你问:

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) 

根据您的需求我建议你看看Django的values_list上查询集类的函数,它可以缩短,在许多简化代码案例。

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) 

相关的文档是herehere

+0

谢谢。所有好的答案。尽管如此,这对我的工作特别有用。 – Dan 2012-01-06 22:04:12

3

看起来你是通过遍历property.split('.')

0

除非select_related每个对象都有一个名为“标题”属性寻找

getattr(getattr(student, property), subproperty) 

您可能能够做的,这将会炸毁。 select_related为学生模型带来了什么?我猜它不仅仅是一个Group对象。您需要将其封装在try/except块中,或者测试该对象以查看它是否与Group类型相同(例如,isinstance(x,Group))。

你究竟在努力实现什么?这似乎有点折磨。此外,我会建议重新标记以使事情更清楚:

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

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

+0

有人可以解释downvote吗?不知道这里有什么问题。 – Tom 2012-01-06 15:36:08

1

,你可以随时使用from functools import reduce

和procced这样的:

reduce(getattr, "some.nested.property".split("."), student)