我正在尝试从 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
要获得 verbose_name,您应该调用
object._meta.get_field('field').verbose_name
category._meta.get_field('name').verbose_name
你可以沿着这些方向尝试一些东西
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
如果你有多个应用程序,这会变得更难,因为你也需要知道应用程序名称,但也许这可以作为参数传入。
这里是关于如何从跨关系查找中查找字段的完整解决方案。这是基于 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