如何在django中获取模型字段及其关系?

时间:2022-04-29 11:47:05

With the following code I can get dict of fields in a list:

使用以下代码,我可以在列表中获得字段的字典:

from django.db import connection

table_info = []
tables = connection.introspection.table_names()
seen_models = connection.introspection.installed_models(tables)
for model in seen_models:
    table = model._meta.db_table
    columns = [field.column for field in model._meta.fields]
    table_info.append((table, columns))

From the above I can get a json encoded file like:

从上面我可以得到一个json编码文件,如:

["account_profile",["id","avatar","owner_id","forums","forum_threads","lct_discussion","organization_id","created_at","updated_at"]]

Note owner_id is a related item, I would like to pull all the related items and create a nested array as a result. I'm not sure how I can modify the above code to achieve this. Any recommendation?

注意owner_id是一个相关的项目,我想拉出所有相关的项目并创建一个嵌套的数组作为结果。我不确定如何修改上面的代码来实现这一点。有什么建议?

2 个解决方案

#1


0  

You may use Field.is_relation to check if a field is a relation to another model and inspect the fields of Field.related_model the same way you do here.

您可以使用Field.is_relation检查字段是否与另一个模型的关系,并检查Field.related_model的字段,方法与此处相同。

I think the best solution would be to write a recursive function but beware of circular relations between models.

我认为最好的解决方案是编写递归函数,但要注意模型之间的循环关系。

#2


0  

I have solved it this way:

我这样解决了:

    table_info = []
    tables = connection.introspection.table_names()
    seen_models = connection.introspection.installed_models(tables)
    for model in seen_models:
        table = model._meta.db_table
        columns = [field.column for field in model._meta.fields]

        # Identify a related field item:
        # Use this to get the related table details
        # Loop the table details and append the columns to the main table columns
        # Results to a nested list with depth of 1
        for field in model._meta.fields:
            if field.get_internal_type() == "ForeignKey":
                related_obj = field.rel.to
                related_table = related_obj._meta.db_table
                columns.append((related_table, [x.column for x in related_obj._meta.fields]))

        table_info.append((table, columns))

Note: I did not want to do it recursively to avoid circular relation as mentioned by @ahumeau. This works well for my needs for now. It give me a depth of 1, i.e doesn't look further of the first item.

注意:我不想递归地去做,以避免@ahumeau提到的循环关系。这对我现在的需求很有效。它给我一个深度为1,即不再看第一项。

#1


0  

You may use Field.is_relation to check if a field is a relation to another model and inspect the fields of Field.related_model the same way you do here.

您可以使用Field.is_relation检查字段是否与另一个模型的关系,并检查Field.related_model的字段,方法与此处相同。

I think the best solution would be to write a recursive function but beware of circular relations between models.

我认为最好的解决方案是编写递归函数,但要注意模型之间的循环关系。

#2


0  

I have solved it this way:

我这样解决了:

    table_info = []
    tables = connection.introspection.table_names()
    seen_models = connection.introspection.installed_models(tables)
    for model in seen_models:
        table = model._meta.db_table
        columns = [field.column for field in model._meta.fields]

        # Identify a related field item:
        # Use this to get the related table details
        # Loop the table details and append the columns to the main table columns
        # Results to a nested list with depth of 1
        for field in model._meta.fields:
            if field.get_internal_type() == "ForeignKey":
                related_obj = field.rel.to
                related_table = related_obj._meta.db_table
                columns.append((related_table, [x.column for x in related_obj._meta.fields]))

        table_info.append((table, columns))

Note: I did not want to do it recursively to avoid circular relation as mentioned by @ahumeau. This works well for my needs for now. It give me a depth of 1, i.e doesn't look further of the first item.

注意:我不想递归地去做,以避免@ahumeau提到的循环关系。这对我现在的需求很有效。它给我一个深度为1,即不再看第一项。