Cómo obtener valores de clave externa con getattr de modelos

Tengo un modelo Project and i am getting the attributes of that with the following instr

attr = getattr(project, 'id', None)

project is the instance, id es el campo y None is the default return type.

My question is: what if I want to get the Foreign Key keys with this?

Get customer name

project.customer.name How to get customer name with the above condition?

Ya probado

if callable(attr):
     context[node][field] = '%s' % attr()

Código actual

context = {'project': {}}
fields = ('id', 'name', 'category', 'created_by', customer)

for field in fields:
    attr = getattr(project, field, None)
        if callable(attr):
            context['project'][field] = '%s' % attr()
        else:
            context['project'][field] = attr

i need to adjust customer object here. that i can give something like customer__name or customer.name in my fields and it get populated with the name of the customer, but i am not sure.

preguntado el 27 de noviembre de 13 a las 06:11

¿Por qué no es project.customer.name cutting it? -

well i want to use getattr to get customer name, i get customr object by this way. getattr(project, 'project.customer', None) but i want something like his name getattr(project, 'project.customer.name', None) -

so name = getattr(project.customer, 'name', None) ¿trabajaría? -

sure do, but i am writing a re-useable code something like that. let me edit the code above -

Code updated @limelights -

2 Respuestas

You can do something like follows:

def get_repr(value): 
    if callable(value):
        return '%s' % value()
    return value

def get_field(instance, field):
    field_path = field.split('.')
    attr = instance
    for elem in field_path:
        try:
            attr = getattr(attr, elem)
        except AttributeError:
            return None
    return attr

for field in fields:
    context['project'][field] = get_repr(get_field(project, field))

respondido 27 nov., 13:08

Perfect, although I'd change attr = getattr(attr, elem) a attr = get_repr(getattr(attr, elem)) - alequisnia

Here's an equivalent recursive getattr -

def get_foreign_key_attr(obj, field: str):
    """Get attr recursively by following foreign key relations

    For example ...
    get_foreign_key_attr(
        <Station: Spire operational 1m>, "idproject__idcountry__name"
    )
    ... splits "idproject__idcountry__name" into ["idproject", "idcountry", "name"]
    & follows finds the value of each foreign key relation
    """
    fields = field.split("__")
    if len(fields) == 1:
        return getattr(obj, fields[0], "")
    else:
        first_field = fields[0]
        remaining_fields = "__".join(fields[1:])
        return get_foreign_key_attr(getattr(obj, first_field), remaining_fields)

respondido 29 nov., 22:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.