Django доступ к связанному свойству динамически? - PullRequest
1 голос
/ 06 января 2012

Я использую getattr для динамического доступа к свойствам модели, например, так (при условии, что модель Стьюдента имеет свойство с именем 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 голосов
/ 06 января 2012

Пока следующий код сделает то, что вы просили:

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 функцию Django в классе Queryset, она может сократить и упростить код во многих случаях.

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)

Соответствующие документы: здесь и здесь .

3 голосов
/ 06 января 2012

похоже, что вы ищете

getattr(getattr(student, property), subproperty)

Вы можете сделать это с помощью цикла property.split('.')

1 голос
/ 15 июля 2015

вы всегда можете использовать from functools import reduce

и обрабатывать так:

reduce(getattr, "some.nested.property".split("."), student)
0 голосов
/ 06 января 2012

Если каждый объект в select_related не имеет свойства под названием title, это может взорваться. Что select_related возвращает для модели Student? Я предполагаю, что это больше, чем просто объект группы. Вам нужно будет обернуть это в блок try / исключением или протестировать объект, чтобы увидеть, относится ли он к тому же типу, что и группа (например, isinstance (x, Group)).

Чего вы на самом деле пытаетесь достичь? Это кажется немного замученным. Кроме того, я бы предложил изменить маркировку, чтобы прояснить ситуацию:

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

Вы на самом деле не получаете объекты Student в этом списке.

...