如何从 Django 中的字符串路径获取模型字段

问题描述 投票:0回答:3

我正在尝试从 Django 中的字符串之类的过滤器中获取字段对象。

例如,

Sale.objects.filter(product__category__name='shoes')

给定模型

Sale
和字符串
"product__category__name"
,是否可以得到
Category.name
的字段对象? (或者更具体地说,那个领域的
verbose_name
)。

更新

这就是我最终想出的

from django.db.models.fields import FieldDoesNotExist

def find_field(model, lookup):
    lookups = list(reversed(lookup.split("__")))
    field = None

    while model and lookups:
        current = lookups.pop()
        field = model._meta.get_field(current)
        model = field.related_model
        if lookups and model is None:
            raise FieldDoesNotExist(lookup)
    return field
django django-1.8
3个回答
1
投票

要获得 verbose_name,您应该调用

object._meta.get_field('field').verbose_name

category._meta.get_field('name').verbose_name

1
投票

你可以沿着这些方向尝试一些东西

def get_verbose_name_from_query_string(query_string):
    query_string = query_string.split('__')[-1].split('_')
    model_name = query_string[0]
    field_name = query_string[1]
    model = apps.get_model('app_name', model_name)
    return model._meta.get_field(field_name).verbose_name

query_string = 'product__category_name'    
get_verbose_name_from_query_string(query_string)

这将返回Name

如果你有多个应用程序,这会变得更难,因为你也需要知道应用程序名称,但也许这可以作为参数传入。


0
投票

这里是关于如何从跨关系查找中查找字段的完整解决方案。这是基于 OP 在问题中给出的很好的答案,但有一些改进和错误修复。

from django.core.exceptions import FieldDoesNotExist
from django.db import models


def find_field_from_lookup(model_class: models.Model, lookup: str) -> models.Field:
    """Find field object from a lookup, which can span relationships.

    Example: `"book__author__name"` would return the `name` field of the `Author` model.

    Raises `FieldDoesNotExist` when the lookup is not valid.
    """
    field_names = list(reversed(lookup.split("__")))
    if not field_names or not model_class:
        raise FieldDoesNotExist(lookup)
    while model_class and field_names:
        field_name = field_names.pop()
        field = model_class._meta.get_field(field_name)
        model_class = field.related_model
        if field_names and not model_class:
            raise FieldDoesNotExist(lookup)
    return field
© www.soinside.com 2019 - 2024. All rights reserved.