我在Django中构建一个项目,需要列出给定模型中的所有字段作为html选择标记的选项。 我写了一个递归函数,它读取模型并返回包含所有字段和子字段的列表。像这样:
def get_fields_true_hierarchy(model, list_fields = []):
fields_obj = model._meta.fields
for field_obj in fields_obj:
if field_obj.rel:
dict_fields = {field_obj.attname: []}
list_fields.append(dict_fields)
get_fields_true_hierarchy(field_obj.rel.to, dict_fields[field_obj.attname])
else:
list_fields.append(field_obj.attname)
return list_fields
返回如下对象:
fiedls = [
'id',
'title',
'number',
'start_date',
'finish_date',
{'status_id':
['id',
'name']
},
'postal_code',
{'requestor_id':
['id',
{'user_id':
['id',
'password',
'last_login',
'is_superuser',
'username',
'first_name',
'last_name',
'email',
'is_staff',
'is_active', '
date_joined']
},
'name',
'phone',
'email',
'contact_name',
'contact_email']
},
{'reason_id':
['id',
'description']
},
'details',
{'group_id':
['id',
'description']
},
{'subgroup_id':
['id',
'description']
},
{'manager_id':
['id',
'password',
'last_login',
'is_superuser',
'username',
'first_name',
'last_name',
'email',
'is_staff',
'is_active',
'date_joined']
},
'datetime_subscription',
'allowed',
'data_def'
]
但是,我需要获得一个单一级别的列表,如下所示:
fiedls = [
'id',
'title',
'number',
'start_date',
'finish_date',
'status_id',
'status_id.id',
'status_id.name',
'postal_code',
'requestor_id',
'requestor_id.id',
'requestor_id.user_id',
'requestor_id.user_id.id',
'requestor_id.user_id.password',
'requestor_id.user_id.last_login',
'requestor_id.user_id.is_superuser',
'requestor_id.user_id.username',
'requestor_id.user_id.first_name',
'requestor_id.user_id.last_name',
'requestor_id.user_id.email',
'requestor_id.user_id.is_staff',
'requestor_id.user_id.is_active',
'requestor_id.user_id.date_joined',
'requestor_id.name',
'requestor_id.phone',
'requestor_id.email',
'requestor_id.contact_name',
'requestor_id.contact_email',
'reason_id',
'reason_id.id',
'reason_id.description',
'details',
'group_id',
'group_id.id',
'group_id.description',
'subgroup_id',
'subgroup_id.id',
'subgroup_id.description',
'manager_id',
'manager_id.id',
'manager_id.password',
'manager_id.last_login',
'manager_id.is_superuser',
'manager_id.username',
'manager_id.first_name',
'manager_id.last_name',
'manager_id.email',
'manager_id.is_staff',
'manager_id.is_active',
'manager_id.date_joined',
'datetime_subscription',
'allowed',
'data_def'
]
我无法写一个递归函数来返回这样的结果。您对如何执行此任务有任何想法吗? 我坚持下面的这个功能。但它的行为并不像预期的那样。
PS。:list_fields
参数将来自get_fields_true_hierarchy()
函数。
def get_fields_fake_hierarchy(list_fields, fake_hierarchy = [], parent_str = "", reset=True):
for field in list_fields:
if reset:
parent_str = ""
if isinstance(field, dict):
for key, value in field.iteritems():
fake_hierarchy.append(key)
parent_str += "."+key
get_fields_fake_hierarchy(value, fake_hierarchy, parent_str, reset=False)
else:
fake_hierarchy.append("%s.%s"%(parent_str, field))
fake_hierarchy = [i[1:] if i[0]=='.' else i for i in fake_hierarchy]
return fake_hierarchy
答案 0 :(得分:3)
改为使用递归生成器,并在运行时为名称添加前缀:
def do_prefix(name, prefix):
if prefix:
return "%s.%s" % (prefix, name)
return name
def get_fields_flat(model):
return [name for name in iter_fields(model)]
def iter_fields(model, prefix=None):
fields = model._meta.fields
for field in fields:
name = do_prefix(field.attname, prefix)
yield name
if field.rel:
rel = field.rel.to
for f in iter_fields(rel, name):
yield f