Search code examples
pythondjangogetattr

Django access related property dynamically?


I am using getattr to access properties of a model dynamically like so (Assuming the Student model has a property called name):

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


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

This works fine, however I'm wondering if it is possible to access a property of a related record in the same way, for example (Assuming each Student has a related Group with a property called title):

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


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

With this, I just get the error 'Student has no attribute group.title'

Is there anyway to achieve this?

Any advice appreciated.

Thanks


Solution

  • While the following code will do what you asked:

    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)
    

    Depending on your needs I would suggest that you look into Django's values_list function on the Queryset class, it can shorten and simplify code in many cases.

    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)
    

    The relevant docs are here and here.