如何找出 Django 字段的 Python 表示?

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

例如我有这个代码:

class SomeModel(models.Model):
    instance_name = models.UnknownField(max_length=255)
    instance_id = models.IntegerField()

我想要将模型名称 (

SomeModel
) 和字段名称(例如
instance_name
)作为输入,并且输出将是该字段的 python 表示形式(例如:srt、int ,漂浮...)

所以会是这样的:

def find_out_the_field_python_type(model: Model, field_name: str) -> type:
    # For example model = SomeModel, field_name = instance_id
    # return int
    return

我试过这个:

instance_id_field = SomeModel._meta.get_field('instance_id')
# Determine the Python representation of the field
python_representation = instance_id_field.get_internal_type()
print(python_representation)
# returns 'IntegerField'

但问题是它返回的不是Python表示,而是Django字段的类型。

django django-models types field
1个回答
0
投票

我认为你想要的东西是不可能实现的。 源代码可用。看来 Python 类型不是元变量,而是硬编码到字段的

to_python
方法中。

模型是Python和数据库之间的接口。并非所有数据库都直接支持所有 Django 字段类型。如果不这样做,Django 会执行编码来存储和解码来初始化模型实例。

例如,这是来自上述来源的 DecimalField 的

to_python
方法:

def to_python(self, value):
    if value is None:
        return value
    if isinstance(value, float):
        return self.context.create_decimal_from_float(value)
    try:
        return decimal.Decimal(value)
    except (decimal.InvalidOperation, TypeError, ValueError):
        raise exceptions.ValidationError(
            self.error_messages['invalid'],
            code='invalid',
            params={'value': value},
        )

如果您确定可以运行迭代,将合理的值输入到

to_python
方法中,直到获得成功返回。在执行此操作之前,您需要检查字段的
concrete
(True)和
is_relation
(False)以进行适当的其他处理。

instance_id_field = SomeModel._meta.get_field('instance_id')
if instance_id_field.is_relation:
    # ??
if not instance.id_field.is_concrete:
    # ??
for thing in (
    '0',         # should work for Charfield and numeric fields and Boolean
    datetime.datetime( 2023,1,1),  # for all date or datetime,
    0.0,                           # for above DecimalField,
    ...                            # work through the above-linked source for other probe values!
):
    try:
        x = instance_id_field.to_python( thing)
        return type(x)
    except Exception:
        pass

raise TypeError( 
    f'Unable to determine Python type of {instance_id_field}')

但这实在是太糟糕了。

© www.soinside.com 2019 - 2024. All rights reserved.