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

How to find out the Python representation of Django fields?

提问人:Ivan 提问时间:11/16/2023 更新时间:11/16/2023 访问量:34

问:

例如,我有以下代码:

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

我想将模型名称 () 和字段名称(例如)作为输入,并且输出将是该字段的 python 表示形式(例如:srt、int、float......SomeModelinstance_name

所以它将是这样的:

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 字段

评论


答:

2赞 nigel222 11/16/2023 #1

我不认为你想要的真的可行。源代码可用。看起来 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},
        )

如果确定,可以运行迭代,将合理的值输入到方法中,直到获得成功的返回。在执行此操作之前,您需要检查字段的 (True) 和 (False) 是否有适当的其他处理。to_pythonconcreteis_relation

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}')

但这真的很可怕。