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

xytpbqjk  于 11个月前  发布在  Go
关注(0)|答案(1)|浏览(97)

例如,我有这样的代码:

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

字符串
我希望有模型名称(SomeModel)和字段名称(例如,instance_name)作为输入,输出将是该字段的Python表示(例如:srt,int,float.)
所以它会是这样的:

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字段的类型。

gpfsuwkq

gpfsuwkq1#

我不认为你想要的是真正可行的。Source code is available。看起来Python类型不是一个Meta变量,而是硬编码到字段的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}')


但这真的是可怕的黑客。

相关问题