获取Django模型字段的Python类型?

7
如何获取Django模型字段类相应的Python类型?
from django.db import models

class MyModel(models.Model):
    value = models.DecimalField()

type(MyModel._meta.get_field('value'))  # <class 'django.db.models.fields.DecimalField'>

我想知道如何获得字段值的对应Python类型,这个例子中是 decimal.Decimal

有什么想法吗?

附注:我已经尝试使用字段的 default 属性来解决此问题,但在没有定义默认值的字段中可能不起作用。


你需要在类上工作吗?因为如果你在实例上工作,每个字段的类型将是Python的m=MyModel() type(m.value) - Pynchia
@Pynchia 是的,我需要处理这个类。我正在生成field_name: value_type字典以进行序列化,与具体模型实例无关。 - joanbm
2个回答

2
我不认为您可以通过程序来决定实际的Python类型。其中一部分原因是由于Python是动态类型语言。如果您查看 将值转换为Python对象 的文档,会发现没有一个硬性的预定义类型适用于字段:您可以编写自定义字段,根据数据库值返回不同类型的对象。 模型字段 的文档指定了每个字段类型对应的Python类型,因此可以静态地进行操作。

但是,为什么需要提前知道Python类型才能序列化它们呢?序列化模块应该为您完成此操作,只需向其传递要序列化的对象即可。Python是动态类型语言。


谢谢你的回答。你可能是对的。我已经瞥了一眼DecimalField的源代码,似乎只有在实例方法(如to_python)中才处理字段值类型。我需要这个功能,因为我正在进行自定义会话序列化/反序列化,其中包括外键字段和其他JSONSerializer不支持的类型,例如decimalfield。除了使用不安全的pickle之外,是否有更规范的方法来序列化这些类型?Django 1.6+中的会话序列化 - joanbm
在自定义序列化器中,Decimal 被转换为字符串(而不是浮点数,因为可能会丢失精度),对于反序列化,我需要知道要将值转换为哪种类型。 - joanbm
如果需要自定义的序列化/反序列化器,请在序列化器中检查类型。在反序列化期间,您将仅获得值而不是其他提示,我无法理解为什么拥有字段名称:值对的字典会有所帮助。@joanbm - Tianwei Chen
序列化/反序列化处理来自会话的数据,它们可能包含来自外部源的值,因此它们是不受信任的。虽然伪造会话值需要 SECRET_KEY 的知识,但建议在 Django 1.6 及更高版本中将其设置为默认值,以避免使用 pickle 并使用 json 序列化器。请参见第二条评论中的链接。 - joanbm
我可能会漏掉一些东西,但是当在序列化时Decimal值被转换为字符串时,反序列化器如何知道该字符串必须转换为Decimal,针对这个特定的字段?我使用field_name → value_type对来解决这个问题。 - joanbm
显示剩余2条评论

0

一个不太优雅的替代方案是检查该字段的 repr() 方法:

if 'DecimalField' in repr(model._meta.get_field(fieldname)):
    return decimal.Decimal
else:
    ...

然而,你必须为所有类型分别执行此操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接